398-A Cards

题目描述:

User ainta loves to play with cards. He has a cards containing letter "o" and b cards containing letter "x". He arranges the cards in a row, and calculates the score of the deck by the formula below.

  1. At first, the score is 0.
  2. For each block of contiguous "o"s with length x the score increases by x2.
  3. For each block of contiguous "x"s with length y the score decreases by y2.
 

For example, if a = 6, b = 3 and ainta have arranged the cards in the order, that is described by string "ooxoooxxo", the score of the deck equals 22 - 12 + 32 - 22 + 12 = 9. That is because the deck has 5 blocks in total: "oo", "x", "ooo", "xx", "o".

User ainta likes big numbers, so he wants to maximize the score with the given cards. Help ainta make the score as big as possible. Note, that he has to arrange all his cards.

输入a,b的值,范围都是10的5次方,输出最大值和对应的排列方式,多种排列方式成立时任意一种都可以;

同样是codeforce的一道题,比较考思维和简单的数学能力,根据题意我们需要让o尽可能连续,让x尽可能的分散才有可能取得最大值,我们从让一整段o将x分割成两段的情况开始讨论。此时有一整段o长度为a,两段x,长度可能都为b/2,或者一段b/2另一段为b/2+1,将a,b的分段情况找出来之后就可以按照题目给的算法算出一个一个sum值;

然后我们再将情况拓展开,假设现在所有的o被分割成了i段,那么此时所有的x就被分割成了i+1段,这i段的o中会有(i-1)段的长度为1,因为拿去用于分割x,剩下的一段就是我们保证的最长连续的o,长度为a-(i-1);

此时的x的被分成i+1段,如果能整除,那么每段的长度就为b/(i+1),如果无法整除呢,我们令b=x(i+1)+y;其中x=b/(i+1),y=b%(i+1),我们假设有p段的长度为x,q段的长度为x+1用一个简单的待定系数法就可以算出q=y=b%(i+1),p=(i+1)-b%(i+1);

这样我们就把可以把这种情况下的sum值算出来,现在由于o最多只有a个所以最多只能被分成a段,那么我们就枚举i从1到a,把每种情况下的sum算出来找到最大的,并把当前的分段情况记录下来用于之后的输出就可以了,下面是AC代码。

#include
#include
#include
#include
#include
#include
#include
using namespace std;
const int MAXM=1000001;
const int INF=0X7fffffff;

long long a,b;

int main()
{
    while(scanf("%I64d%I64d",&a,&b)!=EOF)
    {
        if (a==0)
        {
            long long ans=-b*b;
            printf("%I64d\n",ans);
            for (int j=1;j<=b;j++)
                printf("x");
            printf("\n");
            continue;
        }
        if (b==0)
        {
            long long ans=a*a;
            printf("%I64d\n",ans);
            for (int j=1;j<=a;j++)
                printf("o");
            printf("\n");
            continue;
        }
        long long maxm=-INF;
        int q=0;
        for (int i=1;i<=a;i++)
        {
            long long suma=(i-1)*1+(a-i+1)*(a-i+1);
            //printf("%lld\n",suma);
            long long sumb=(b%(i+1))*(b/(i+1)+1)*(b/(i+1)+1)+(i+1-b%(i+1))*(b/(i+1))*(b/(i+1));
            //printf("%lld\n",sumb);
            long long sum=suma-sumb;
            if (sum>maxm)
            {
                maxm=sum;
                q=i;
            }
        }
        printf("%I64d\n",maxm);
        int y=b%(q+1);
        int x=b/(q+1);
        for (int i=1;i<=q+1;i++)
        {

           if (y)
           {
               for (int j=1;j<=x+1;j++)
                printf("x");
                y--;
           }
           else
           {
               for (int j=1;j<=x;j++)
                printf("x");
           }
           if (i==q+1)
            break;
           if (i==1)
           {
               for (int j=1;j<=(a-(q-1));j++)
                printf("o");
           }
           else
            printf("o");
        }
        printf("\n");
    }
    return 0;
}



你可能感兴趣的:(思维)