CodeForces 398A Cards

昨天搬了一下午的原博客……
晚上玩了一下就没写了

今天补上这道

题意:
xn个x卡片和on和o卡片,让你摆放。
每个x卡连续形成xlen 则减去 xlen×xlen
每个o卡连续形成olen 则减去 olen×olen

思路:
枚举分割的段数,直接暴力做……

但是我在一个地方思想出了偏差……一直得不到正解。
就是当我分割成split段时,长度为 cnum = xn / split ,这是偏小的,可以有 mod = xn % split 个 cnum + 1 个

AC Code

#include <algorithm>
#include <cctype>
#include <cmath>
#include <cstdio>
#include <cstring>
#include <iostream>
#include <queue>
#include <stack>
#include <vector>

#define ll long long
#define each(i, n) for (int(i) = 0; (i) < (n); (i)++)
#define reach(i, n) for (int(i) = n - 1; (i) >= 0; (i)--)
#define range(i, st, en) for (int(i) = (st); (i) <= (en); (i)++)
#define rrange(i, st, en) for (int(i) = (en); (i) >= (st); (i)--)
#define fill(num, ary) memset((ary), (num), sizeof((ary)))

using namespace std;

const int maxn = 2e5 + 5;
const ll inf = 0x3f3f3f3f3f3f3f3f;

long long xn, on;

inline long long mul(const long long& x)
{
    return x * x;
}

inline void output(int len)
{
    ll cnum = xn / len, mod = xn % len;
    each(i, len-1)
    {
        if (i)
            putchar('o');
        each(j, cnum)
            putchar('x');
        if (i < mod)
            putchar('x');
    }
    each(i, on - len + 2)
        putchar('o');
    each(i, cnum)
        putchar('x');
}

int main()
{
    scanf("%lld %lld", &on, &xn);
    if (on == 0) {
        printf("%lld\n", -xn * xn);
        each(i, xn)
            putchar('x');
    } else if (xn == 0) {
        printf("%lld\n", on * on);
        each(i, on)
            putchar('o');
    } else {
        ll ans = -inf, cans, split = 1, len = 1;
        while (split <= on) {
            ll cnum = xn / (split + 1), mod = xn % (split + 1);
            cans = mul(on - split + 1) + split - 1 - mod * mul(cnum + 1) - (split + 1 - mod) * mul(cnum);
            if (cans > ans) {
                len = split;
                ans = cans;
            }
            split++;
        }
        printf("%lld\n", ans);
        output(len + 1);
    }
    return 0;
}