牛客练习赛59 A小乔和小灰灰(模拟)+B牛能和小镇(思维)+C装备合成(三分)+D取石子游戏(博弈)
地址:https://ac.nowcoder.com/acm/contest/4743#question
解析:简单模拟。其实我写的并不简单,太尴尬了。第一个是我的,第二个借鉴别人的。
#include<iostream> #include<cstdio> #include<cstring> #include<algorithm> #include<set> using namespace std; typedef long long ll; const int maxn=1e3+10; char s[maxn]; char fir[6]="Xiao"; char qiao[6]="Qiao"; char hui[5]="Hui"; int main() { cin>>s; int k=-1; //Xi int len=strlen(s); int tot=0; int ok1=0; int mid1; for(int i=0;i<len;i++) { if(s[i]==fir[tot]) { if(fir[tot]=='o') { mid1=i; ok1=1;break; } tot++; } } tot=0; int ok2=0; for(int i=mid1+1;i<len;i++) { if(s[i]==qiao[tot]) { if(qiao[tot]=='o') { ok2=1; break; } tot++; } } int ok3=0; tot=0; int mid2; for(int i=mid1+1;i<len;i++) { if(s[i]==hui[tot]) { if(hui[tot]=='i') { ok3=1; mid2=i;break; } tot++; } } int ok4=0;tot=0; for(int i=mid2+1;i<len;i++) { if(s[i]==hui[tot]) { if(hui[tot]=='i') { ok4=1;break; } tot++; } } if(ok1==0||ok2==0||ok3==0||ok4==0) cout<<"emm"<<endl; else cout<<"Happy"<<endl; }
#include<iostream> #include<cstdio> #include<cstring> #include<algorithm> #include<set> using namespace std; char s1[10]="XiaoQiao"; char s2[20]="XiaoHuiHui"; int main() { char s[1005]; cin>>s; int x1=0,x2=0; for(int i=0;i<strlen(s);i++) { if(s[i]==s1[x1]) x1++; if(s[i]==s2[x2]) x2++; } // cout<<x1<<" "<<x2<<endl; if(x1==8&&x2==10) cout<<"Happy"<<endl; else cout<<"emm"<<endl; }
题意:中文题意,不写了。
解析:这个式子把我搞懵了,完全被某种东西蒙蔽了双眼,纠结于化简(a+b)^3之类的。实际上仔细观察一下原式,换一下就是:xi^2*yi+yi^2(yi-2*xi^2)-(同前,换成j即可)。所以我们只要把每一个坐标的x*x*y+y*y*(y-2*x*x)存一下,sort一下保证差最小,然后输出a[n-1]-a[0]就好了,为什么可以直接减呢,比如a,b,c。sum=b-a+c-b=c-a。一样的。
#include<iostream> #include<cstdio> #include<cstring> #include<algorithm> #include<set> using namespace std; typedef long long ll; const int maxn=1e5+10; ll a[maxn]; int main() { int n; cin>>n; for(int i=0;i<n;i++) { ll x,y; cin>>x>>y; a[i]=x*x*y+y*y*(y-2*x); } sort(a,a+n); cout<<a[n-1]-a[0]<<endl; }
题意:中文题意。
解析:2a+3b////4a+b
假设对于2a+3b这个组合生成了n件,那么第二个组合就是min(x-2n/4,y-3n);那么总的就是sum=n+min(x-2n/4,y-3n);n范围(x/2,y/3);看数据,枚举是不可能了。我们要求最大值,所以对于这个sum函数,目测是个凸性函数。可以采用三分的做法。注意一下,r-l>2。防止死循环。
#include<iostream> #include<cstdio> #include<cstring> #include<algorithm> #include<set> using namespace std; typedef long long ll; const int maxn=1e5+10; ll a[maxn]; ll x,y; ll ac(ll i) { return min((x-2*i)/4,y-3*i); } int main() { int t; cin>>t; while(t--) { cin>>x>>y; ll sum=-1; ll l=0,r=min(x/2,y/3); while(r-l>2) { ll mid=(l+r)/2; ll mmid=(r+mid)/2; if((mid+ac(mid))>(mmid+ac(mmid))) { r=mmid; } else l=mid; // cout<<l<<"-"<<r<<endl; } ll maxx=-1; for(ll i=l;i<=r;i++) { maxx=max(maxx,i+ac(i)); } cout<<maxx<<endl; } }
题意:中文题意
解析:说实话,不好好读题的话,这个很容易懵。我是这么画的:
画的不好见谅哈哈,操作是,分完再选一堆给另一个人,这个要分清。所以谁最后得到2,谁就赢了。根据前10个的观察,得到结论:给出的n,变成1,需要/2多少次?求出这个次数ans,是奇数的话,就是hui赢,否则是qiao。这个操作,我们需要从1开始倒着看,推到n。这个操作是从一个学长那得到的,我自己没想到。
#include<iostream> #include<cstdio> #include<cstring> #include<algorithm> #include<set> using namespace std; typedef long long ll; int main() { int t; scanf("%d",&t); while(t--) { ll n; scanf("%lld",&n); ll ans=1,sum=1; while(sum<n) { if(ans%2!=0) sum=sum*2+1; else sum=sum*2; ans++; } ans--; if(ans%2==0) cout<<"XiaoQiao"<<endl; else cout<<"XiaoHuiHui"<<endl; } }