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了几次,读对题很重要。