题目链接:
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; }
Codeforces Round #233 (Div. 1) <A>,布布扣,bubuko.com
Codeforces Round #233 (Div. 1) <A>
原文:http://blog.csdn.net/cc_again/article/details/20778557