C. Absolute Zero
time limit per test: 2 seconds
memory limit per test: 256 megabytes
input: standard input
output: standard output
You are given an array \(a\) of \(n\) integers.
In one operation, you will perform the following two-step move:
- Choose an integer \(x\) (\(0 \le x \le 10^{9}\)).
- Replace each \(a_i\) with \(|a_i - x|\), where \(|v|\) denotes the absolute value of \(v\).
For example, by choosing \(x = 8\), the array \([5, 7, 10]\) will be changed into \([|5-8|, |7-8|, |10-8|] = [3,1,2]\).
Construct a sequence of operations to make all elements of \(a\) equal to \(0\) in at most \(40\) operations or determine that it is impossible. You do not need to minimize the number of operations.
给你一个由 \(n\) 个整数组成的数组 \(a\) 。
在一次操作中,您将执行以下两步移动:
- 选择一个整数 \(x\) ( \(0 \le x \le 10^{9}\) )。
- 将每个 \(a_i\) 替换为 \(|a_i - x|\) ,其中 \(|v|\) 表示 \(v\) 的 绝对值。
例如,选择 \(x = 8\) 后,数组 \([5, 7, 10]\) 将变为 \([|5-8|, |7-8|, |10-8|] = [3,1,2]\) 。
构建一个操作序列,使 \(a\) 中的所有元素在最多 \(40\) 次操作中等于 \(0\) ,或者确定这是不可能的。您不需要****尽量减少运算次数。
Input
Each test contains multiple test cases. The first line contains a single integer \(t\) (\(1 \le t \le 10^4\)) — the number of test cases. The description of test cases follows.
The first line of each test case contains a single integer \(n\) (\(1 \le n \le 2 \cdot 10^5\)) — the length of the array \(a\).
The second line of each test case contains \(n\) integers \(a_1, a_2, \ldots, a_n\) (\(0 \le a_i \le 10^9\)) — the elements of the array \(a\).
It is guaranteed that the sum of \(n\) over all test cases does not exceed \(2 \cdot 10^5\).
输入
每个测试包含多个测试用例。第一行包含一个整数 \(t\) ( \(1 \le t \le 10^4\) )--测试用例数。( \(1 \le t \le 10^4\) )--测试用例的数量。测试用例说明如下。
每个测试用例的第一行都包含一个整数 \(n\) ( \(1 \le n \le 2 \cdot 10^5\) ) - 数组 \(a\) 的长度。
每个测试用例的第二行包含 \(n\) 个整数 \(a_1, a_2, \ldots, a_n\) ( \(0 \le a_i \le 10^9\) ) - 数组 \(a\) 的元素。
保证所有测试用例中 \(n\) 的总和不超过 \(2 \cdot 10^5\) 。
Output
For each test case, output a single integer \(-1\) if it is impossible to make all array elements equal to \(0\) in at most \(40\) operations.
Otherwise, output two lines. The first line of output should contain a single integer \(k\) (\(0 \le k \le 40\)) — the number of operations. The second line of output should contain \(k\) integers \(x_1, x_2, \ldots, x_k\) (\(0 \le x_i \le 10^{9}\)) — the sequence of operations, denoting that on the \(i\)-th operation, you chose \(x=x_i\).
If there are multiple solutions, output any of them.
You do not need to minimize the number of operations.
输出
对于每个测试用例,如果不可能在最多 \(40\) 次操作中使所有数组元素等于 \(0\) ,则输出一个整数 \(-1\) 。
否则,输出两行。第一行输出应包含一个整数 \(k\) ( \(0 \le k \le 40\) ) - 运算次数。第二行输出应该包含 \(k\) 个整数 \(x_1, x_2, \ldots, x_k\) ( \(0 \le x_i \le 10^{9}\) ) - 运算序列,表示在 \(i\) -th 运算中,你选择了 \(x=x_i\) 。
如果有多个解,请输出其中任意一个。
您无需最小化操作次数。
Example
Input
5
1
5
2
0 0
3
4 6 8
4
80 40 20 10
5
1 2 3 4 5
Output
1
5
0
3
6 1 1
7
60 40 20 10 30 25 5
-1
Note
In the first test case, we can perform only one operation by choosing \(x = 5\), changing the array from \([5]\) to \([0]\).
In the second test case, no operations are needed because all elements of the array are already \(0\).
In the third test case, we can choose \(x = 6\) to change the array from \([4, 6, 8]\) to \([2, 0, 2]\), then choose \(x = 1\) to change it to \([1, 1, 1]\), and finally choose \(x = 1\) again to change the array into \([0, 0, 0]\).
In the fourth test case, we can make all elements \(0\) by following the operation sequence \((60, 40, 20, 10, 30, 25, 5)\).
In the fifth test case, it can be shown that it is impossible to make all elements \(0\) in at most \(40\) operations. Therefore, the output is \(-1\).
注
在第一个测试用例中,我们只需选择 \(x = 5\) ,将数组从 \([5]\) 变为 \([0]\) ,就可以执行一次操作。
在第二个测试用例中,不需要进行任何操作,因为数组的所有元素都已经是 \(0\) 。
在第三个测试用例中,我们可以选择 \(x = 6\) 将数组从 \([4, 6, 8]\) 变为 \([2, 0, 2]\) ,然后选择 \(x = 1\) 变为 \([1, 1, 1]\) ,最后再次选择 \(x = 1\) 变为 \([0, 0, 0]\) 。
在第四个测试用例中,我们可以按照 \((60, 40, 20, 10, 30, 25, 5)\) 的操作序列将所有元素变为 \(0\) 。
在第五个测试用例中,我们可以证明不可能在最多 \(40\) 次操作中将所有元素变为 \(0\) 。因此,输出为 \(-1\) 。
题意
给你一个数组 \(a\)
你可以对数组 \(a\) 做一种操作:选择一个数字 \(x\),使a中的所有元素变成 a与x的差的绝对值
问:能否通过不超过 \(40\) 次操作,使数组的所有元素变成 \(0\)
题解
看到 40
这个数字,有没有什么感觉
刚刚好没有超过 32
啊(联想一下 2^32
)
那是不是可以二分呢??我们再看看
假如说一个我选择一个数 \(x\) ,使所有数字变成 \(|a_i - x|\)
那么我们可以看得出来,只要 \(a_i \le x \times 2\)
就能得到: \(|a_i - x| \le x\)
即使最初的这个数很大很大(甚至 \(1 \times 10^9\) )
我也能一层一层二分给他削减下去,直到最后为 \(0\)
注:因为数字不能超过\(1 \times 10^9\),所以我们只能从 \(2^{30}\) 开始往下减
第二个问题:怎么确认一个数组里面全部数字能不能变成 \(0\) ?
已知:
- 奇数相减/偶数相减 得到的只会是偶数
- 奇偶相减 得到的只会是奇数
我们来对比一下:
- 奇数
- 和奇数相减 偶数
- 和偶数相减 奇数
- 偶数
- 和奇数相减 奇数
- 和偶数相减 偶数
我们可以看到
- 不管是奇数还是偶数,和奇数相减,奇偶性改变
- 不管是奇数还是偶数,和偶数相减,奇偶性不变
也就是说,不管我怎么操作,他们的奇偶性相对而言都是不变的
而最后我们要全部变成0
说明奇偶性要一致
所以我们只要判断是不是全部是奇数或者偶数就可以了
- 是,就可以全部变成0
- 不是,就不可以
PS:
从这里我们又能看到,因为 \(2\) 的任意次方都是偶数,没有改变奇偶性( \(0\) 次方除外)
所以假如数组全部是偶数的话,减去一个 \(1\) 之后奇偶性改变,要再减去一个 \(1\)
代码
#include <bits/stdc++.h>
#define int long long
int bii[30];
void init() {
bii[0] = 1;
for(int i = 1 ; i < 30 ; i ++) bii[i] = bii[i-1] * 2;
}
void solve() {
int n,num,n1;
std::cin >> n;
int ji=0,ou=0;
for(int i = 0 ; i < n ; i ++) {
std::cin >> num;
if(num % 2 == 1) ji++;
else ou++;
}
if(ji > 0 && ou > 0) std::cout << -1 << "\n";
else {
std::cout << 30 + (ou ? 1 : 0) << "\n";
for(int i = 29 ; i >= 0 ; i --) {
std::cout << bii[i] << " ";
}
if(ou > 0) std::cout << 1;
std::cout << "\n";
}
}
signed main() {
std::ios::sync_with_stdio(false);
std::cin.tie(nullptr);
std::cout.tie(nullptr);
init();
int t;
std::cin >> t;
while(t--) {
solve();
}
return 0;
}
标签:10,le,题解,40,偶数,测试用例,test,Div,Round
From: https://www.cnblogs.com/jiejiejiang2004/p/18336168