题意:
a个o b个x 排在一条线上 排列的得分计算方法是 连续y个o就+y^2 连续y个x就-y^2 问 最大得分和排列方式
思路:
直接想到xxooooox这种排列的方式 然后交 然后WA - -b
看了下题解才意识到 增加o的份数虽然会影响+的分 但是可以缩小-的分 (我之前一直认为分开o不好…)
然后就是枚举o的份数即可 x的份数能比o多就多一份
为了+的尽量大 o的分布应该集中 所以就除了一组以外其他都是1
为了-的尽量小 x就应该平摊
代码:
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
__int64 a,b,val,ans,tmp;
int main()
{
int i,j,ta,tb;
scanf("%I64d%I64d",&a,&b);
if(!a)
{
printf("%I64d\n",-b*b);
while(b--) printf("x");
printf("\n");
return 0;
}
if(!b)
{
printf("%I64d\n",a*a);
while(a--) printf("o");
printf("\n");
return 0;
}
val=a*a-b*b; ans=1;
for(i=1;i<=a;i++)
{
if(b>=i+1) j=i+1;
else break;
tmp=( (a-i+1)*(a-i+1) + i-1 ) - ( (b/j+1)*(b/j+1)*(b%j) + (b/j)*(b/j)*(j-b%j) );
//printf("%d %I64d\n",i,tmp);
if(tmp>val)
{
val=tmp;
ans=i;
}
}
printf("%I64d\n",val);
ta=ans-1;
tb=b%(ans+1);
for(i=1;i<=ans*2+1;i++)
{
if(i&1)
{
if(tb)
{
j=b/(ans+1)+1;
tb--;
}
else j=b/(ans+1);
while(j--) printf("x");
}
else
{
if(ta)
{
j=1;
ta--;
}
else j=a-ans+1;
while(j--) printf("o");
}
}
printf("\n");
return 0;
}