http://codeforces.com/gym/101778
周天的比赛做的实在是不怎么样,比赛大都是思维题,这方面的确该加强一下了。
给出两个数n和a,n代表区间长度,a表示该区间和的平均值。问在长度为n的序列中最多有多少个不相同的元素在平均值为a的前提下。
当时做的时候,WA了好几遍,一直以为直接模拟一下就可以出来。事后看题解,也是好久才弄明白思路。
贪心+二分。一共有n个数,最终的和一定为n*a。在每个位置上放1,还有n*(a-1)未放。继续放,使前x个数不同,使x尽量大。第一个数为1,第二个为2,第x个数为x。前x个数的和为x*(x+1)/2,剩下n-x个数放在后面。n*(a-1)-x*(x-1)/2>=0,使x尽量大,求解x的值。二分求解。
#include<bits/stdc++.h> using namespace std; typedef long long ll; int main() { int T; scanf("%d",&T); while(T--) { ll n,a; scanf("%lld%lld",&n,&a); ll l=1;ll r=n;//二分找最多有多少个不同的数 while(l+1<r) { ll mid=(l+r)/2; if(mid*(mid+1)/2+n-mid<=n*a) l=mid; else r=mid-1; } ll ans; if(r*(r+1)/2+n-r<=n*a) ans=r; else ans=l; printf("%lld\n",ans); } return 0; }
G. Preparing for Exams
算是比较简单的数学题了,如果能推出公示的话。
#include<bits/stdc++.h> using namespace std; int main() { int T; scanf("%d",&T); while(T--) { double a,b,s1,s2; scanf("%lf%lf%lf%lf",&a,&b,&s1,&s2); double x=b/(sqrt(s1/s2))-a; double y=a/(sqrt(s1/s2))-b; printf("%lf %lf\n",y,x); } return 0; }
也可以用割线定理,也可以直接求相似,利用相似公式。
H. Genta Game
直接模拟,随时更新,随时计算符合回文串要求的字母对数,如果符合字母对数=n/2,ans++;
#include<bits/stdc++.h> using namespace std; string s; int main() { int T; scanf("%d",&T); while(T--) { int n,m,i; scanf("%d%d",&n,&m); cin>>s; int t=0; for(i=0;i<(n+1)/2;i++) if(s[i]==s[n-i-1]) t++; int sum=(n+1)/2; int ans=0; while(m--) { int x; char ch; scanf("%d %c",&x,&ch); //cout<<"! "<<s[n-x]<<endl; if(s[n-x]==s[x-1]) { s[x-1]=ch; if(s[n-x]!=ch) t--; } else { s[x-1]=ch; if(s[n-x]==ch) t++; } if(t==sum) ans++; } cout<<ans<<endl; } return 0; }I题就相当水了,但也WA了几次,读对题很重要。