CF1463-B. Find The Array
题意:
给出一个由n个数组成的数组a,这个数组的元素和为S,要求你找出一个由n个数字组成数组b,这个数组满足:
-
数组中的每个数可以将他两边的数字整除或者被他两边的数字整除
-
数组b中每个位置的数字减去数组a中相应位置的数字的绝对值和的二倍小于等于S
输出任意一个满足的数组b
思路:
考虑到1可以整除任何数字,那么可以让1作为桥梁,两边可以放置任意数字就可以构造出一个符合第一个要求的数组b,之后也可以按照这个思路进行构造。
现在我们可以想到,让较小的数字减去1,让较大的数字减去我们任意放置的数字,这样可以让最终求出来的和尽量小,那么这个任意放置的数字是多少的时候可以让最终求出来的和尽量小呢?让较大的数字减去他自己是最小的。
最后要考虑的是,我们应该把1这个跳板放在什么位置呢?我们可以按照数组a下表的奇偶统计他们和分别是多少,这样将1放在和较小的位置上。比如奇数位置上和较小,那么构造出来的b数组就是\(\{a_0, 1, a_2, 1, a_4, 1...\}\), 同理偶数。
AC代码:
#include <cstdio>
#include <cstring>
typedef long long ll;
const int maxn = 55;
ll a[maxn];
int main () {
int T, n;
scanf ("%d", &T);
while (T--) {
scanf ("%d", &n);
ll t[2] = {0, 0};
for (int i = 0; i < n; i++) {
scanf ("%lld", &a[i]);
t[i & 1] += a[i];
}
for (int i = 0; i < n; i++) {
if (t[0] > t[1]) {
printf ("%lld%c", i & 1 ? 1 : a[i], " \n" [i == n - 1]);
} else {
printf ("%lld%c", i & 1 ? a[i] : 1, " \n" [i == n - 1]);
}
}
}
return 0;
}