题解 | #D 与数列#
D 与数列
https://ac.nowcoder.com/acm/problem/229428
内测一血。
考虑先满足中位数为 的条件:
构造
不难发现此时一定满足中位数为 。
然后就是考虑如何让平均数为 了,由于这题对于 的值域限制放得很宽,可以考虑把这个影响均摊到剩余的所有数上,具体的做法是:
- 分类讨论。
- 若当前平均数 ,证明需要调大,就将 (差值)摊到后面的 上。
- 若当前平均数 ,证明需要调小,就将 (差值)摊到前面的 上。
具体的“摊”法是:
- 构建一个 for 循环,首先将 计算出来,然后计算出 除以数的个数 下取整的值,这个值摊到每个 上,剩下来的余数直接扔给首/末元素即可。
signed main(){
int n = init(), A = init(), B = init();
for (int i = 1; i <= n; ++i)
if (i == (n + 1) / 2) a[i] = A;
else if (i < (n + 1) / 2) a[i] = A - 1;
else if (i > (n + 1) / 2) a[i] = A + 1;
int sum = 0;
for (int i = 1; i <= n; ++i) sum += a[i];
sum -= n * B;
if (sum == 0) { for (int i = 1; i <= n; ++i) print(a[i]), putchar(' '); } // 恰好可行直接输出
else if (sum < 0) { // 小了就调大
int now = -sum, num = n - (n + 1) / 2;
for (int j = (n + 1) / 2 + 1; j <= n; ++j) a[j] += now / num; // 把“影响”摊给每个数
a[n] += now % num;
for (int i = 1; i <= n; ++i) print(a[i]), putchar(' ');
}
else { // 大了就调小
int now = sum, num = (n + 1) / 2 - 1;
for (int j = 1; j <= num; ++j) a[j] -= now / num; // 把“影响”摊给每个数
a[1] -= now % num;
for (int i = 1; i <= n; ++i) print(a[i]), putchar(' ');
}
}