题目链接:
http://codeforces.com/problemset/problem/398/A
题目意思:
有a个‘o',b个’x',连续相同的字母组成一个块,如果块'o'的个数为x,则分数加上x^2,如果块‘x'的个数为y,则分数减去y^2。开始分数为0,求怎样分块使最终的分数最大。
解题思路:
枚举+贪心。
分析知,要把x的块的长度尽量的安排均匀,o的块尽量在一起。但如果把所有的o都安排在一起的话,也不一定是最优的,可以拿一个出来,把x再多分一份。所以可以枚举o分得1个的个数(i-1),其余的o是连续的,一共把x分成(i+1)份,使这(i+1)份尽可能均匀。
代码:
//#include<CSpreadSheet.h>
#include<iostream>
#include<cmath>
#include<cstdio>
#include<sstream>
#include<cstdlib>
#include<string>
#include<string.h>
#include<cstring>
#include<algorithm>
#include<vector>
#include<map>
#include<set>
#include<stack>
#include<list>
#include<queue>
#include<ctime>
#include<bitset>
#define eps 1e-6
#define INF 0x3f3f3f3f
#define PI acos(-1.0)
#define ll __int64
#define LL long long
#define lson l,m,(rt<<1)
#define rson m+1,r,(rt<<1)|1
#define M 1000000007
//#pragma comment(linker, "/STACK:1024000000,1024000000")
using namespace std;
ll a,b;
ll ans;
int main()
{
//freopen("in.txt","r",stdin);
//freopen("out.txt","w",stdout);
while(~scanf("%I64d%I64d",&a,&b))
{
if(!a||b<=1) //直接输出
{
printf("%I64d\n",a*a-b*b);
for(int i=1;i<=a;i++)
printf("o");
for(int i=1;i<=b;i++)
printf("x");
putchar('\n');
continue;
}
ll ans=(ll)(-1e18); //初始化一个最小值
//printf(":%I64d\n",ans);
ll re1=0;
for(int i=1;i<=a;i++) //分成i-1个1和1个(n-(i-1))两部分
{
if(i>=b) //总分数已大于b了
break;
ll temp=b/(i+1); //每份的个数
ll mo=b%(i+1); //多余的 在分给前mo份
ll cur=(a-(i-1))*(a-i+1)+(i-1)-mo*(temp+1)*(temp+1)-temp*temp*(i+1-mo);
//temp+1的有mo个 temp有(i+1-mo)个
if(cur>ans) //更新结果
{
ans=cur;
re1=i;
}
}
printf("%I64d\n",ans);
ll temp=b/(re1+1); //每份的个数
ll mo=b%(re1+1); //多余的 再给前mo份一份加一个
for(int i=1;i<=temp;i++)
printf("x");
if(mo)
{
printf("x");
mo--;
}
for(int i=2;i<=re1+1;i++)
{
if(i==2)
{
for(int j=1;j<=(a-(re1-1));j++) //先输出(n-(i-1))
printf("o");
}
else
printf("o");
for(int j=1;j<=temp;j++)
printf("x");
if(mo)
{
printf("x");
mo--;
}
}
putchar('\n');
}
return 0;
}