昨天搬了一下午的原博客……
晚上玩了一下就没写了
今天补上这道
题意:
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;
}