题意:有两种字符x和o,计算相同的连续字符的个数的平方,然后用o的平方和减去x的平方和,求最大的结果,并输出相应的序列。
分析:
数论知识是:要使o1^2+o2^2+.....尽可能的大,就要让o尽量凑到一起使它尽量长;要使x1^2+x2^2+.....尽可能的小,就要尽量分散他们,因此每次分的时候采用均分的方式
用上面的理论为基础,然后枚举把o和x分的块数,不断更新结果。每一块的长度用上面的理论加上块数是可以求出来的。
错误原因:
1.TLE:循环变量的数据类型错了。因为这里a和b是long long ,所以循环变量也要设成long long
2.WA:还是long long的问题,之前改了但是不仔细,输入和一个输出用的%d
代码:
#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cstring>
//#define min(a,b) a<b?a:b //经测试直接用define也行,并不是错误原因
#define INF 1000000007
using namespace std;
long long a,b;
long long mi;
long long min(long long a,long long b)
{
return a<b?a:b;
}
int main()
{
while(cin>>a>>b){
if(a==0){
cout<<"-"<<b*b<<endl;
for(int i=0;i<b;i++) cout<<"x";
cout<<endl;
}
else if(b<=1){
cout<<a*a-b*b<<endl;
for(int i=0;i<a;i++) cout<<"o";
for(int i=0;i<b;i++) cout<<"x";
cout<<endl;
}
else{
long long ans=-(a+b)*(a+b);
long long o,x;
mi=min(a,b);
for(long long i=1;i<=mi;i++){
long long a1=(i-1)+(a-(i-1))*(a-(i-1));
for(long long j=i-1;j<=i+1;j++){
if(j>0&&j<=b){
long long b1=(b/j)*(b/j)*(j-b%j)+(b/j+1)*(b/j+1)*(b%j);
long long s=a1-b1;
if(ans<s){
ans=s;
o=i,x=j;
}
}
}
}
cout<<ans<<endl;
if(o>=x){
for(long long i=1;i<=o;i++){
long long len1,len2;
if(i==1) len1=a-(o-1);
else len1=1;
if(i<=b%x) len2=b/x+1;
else len2=b/x;
for(long long j=0;j<len1;j++) cout<<"o";
if(i<=x) for(long long j=0;j<len2;j++) cout<<"x";
}
cout<<endl;
}
else{
for(long long i=1;i<=x;i++){
long long len1,len2;
if(i<=b%x) len2=b/x+1;
else len2=b/x;
if(i==1) len1=a-(o-1);
else len1=1;
for(long long j=0;j<len2;j++) cout<<"x";
if(i<=o) for(long long j=0;j<len1;j++) cout<<"o";
}
cout<<endl;
}
}
}
}