C. Absolute Zero
time limit per test: 2 seconds
memory limit per test: 256 megabytes
input: standard input
output: standard output
给你一个由 n n n 个整数组成的数组 a a a 。
在一次操作中,您将执行以下两步移动:
- 选择一个整数 x x x ( 0 ≤ x ≤ 1 0 9 0 \le x \le 10^{9} 0≤x≤109 )。
- 将每个 a i a_i ai 替换为 ∣ a i − x ∣ |a_i - x| ∣ai−x∣ ,其中 ∣ v ∣ |v| ∣v∣ 表示 v v v 的 绝对值。
例如,选择 x = 8 x = 8 x=8 后,数组 [ 5 , 7 , 10 ] [5, 7, 10] [5,7,10] 将变为 [ ∣ 5 − 8 ∣ , ∣ 7 − 8 ∣ , ∣ 10 − 8 ∣ ] = [ 3 , 1 , 2 ] [|5-8|, |7-8|, |10-8|] = [3,1,2] [∣5−8∣,∣7−8∣,∣10−8∣]=[3,1,2] 。
构建一个操作序列,使 a a a 中的所有元素在最多 40 40 40 次操作中等于 0 0 0 ,或者确定这是不可能的。您不需要****尽量减少运算次数。
Input
每个测试包含多个测试用例。第一行包含一个整数 t t t ( 1 ≤ t ≤ 1 0 4 1 \le t \le 10^4 1≤t≤104 )–测试用例数。( 1 ≤ t ≤ 1 0 4 1 \le t \le 10^4 1≤t≤104 )–测试用例的数量。测试用例说明如下。
每个测试用例的第一行都包含一个整数 n n n ( 1 ≤ n ≤ 2 ⋅ 1 0 5 1 \le n \le 2 \cdot 10^5 1≤n≤2⋅105 ) - 数组 a a a 的长度。
每个测试用例的第二行包含 n n n 个整数 a 1 , a 2 , … , a n a_1, a_2, \ldots, a_n a1,a2,…,an ( 0 ≤ a i ≤ 1 0 9 0 \le a_i \le 10^9 0≤ai≤109 ) - 数组 a a a 的元素。
保证所有测试用例中 n n n 的总和不超过 2 ⋅ 1 0 5 2 \cdot 10^5 2⋅105 。
Output
对于每个测试用例,如果不可能在最多 40 40 40 次操作中使所有数组元素等于 0 0 0 ,则输出一个整数 − 1 -1 −1 。
否则,输出两行。第一行输出应包含一个整数 k k k ( 0 ≤ k ≤ 40 0 \le k \le 40 0≤k≤40 ) - 运算次数。第二行输出应该包含 k k k 个整数 x 1 , x 2 , … , x k x_1, x_2, \ldots, x_k x1,x2,…,xk ( 0 ≤ x i ≤ 1 0 9 0 \le x_i \le 10^{9} 0≤xi≤109 ) - 运算序列,表示在 i i i -th 运算中,你选择了 x = x i x=x_i x=xi 。
如果有多个解,请输出其中任意一个。
您无需最小化操作次数。
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
在第一个测试用例中,我们只需选择 x = 5 x = 5 x=5 ,将数组从 [ 5 ] [5] [5] 变为 [ 0 ] [0] [0] ,就可以执行一次操作。
在第二个测试用例中,不需要进行任何操作,因为数组的所有元素都已经是 0 0 0 。
在第三个测试用例中,我们可以选择 x = 6 x = 6 x=6 将数组从 [ 4 , 6 , 8 ] [4, 6, 8] [4,6,8] 变为 [ 2 , 0 , 2 ] [2, 0, 2] [2,0,2] ,然后选择 x = 1 x = 1 x=1 变为 [ 1 , 1 , 1 ] [1, 1, 1] [1,1,1] ,最后再次选择 x = 1 x = 1 x=1 变为 [ 0 , 0 , 0 ] [0, 0, 0] [0,0,0] 。
在第四个测试用例中,我们可以按照 ( 60 , 40 , 20 , 10 , 30 , 25 , 5 ) (60, 40, 20, 10, 30, 25, 5) (60,40,20,10,30,25,5) 的操作序列将所有元素变为 0 0 0 。
在第五个测试用例中,我们可以证明不可能在最多 40 40 40 次操作中将所有元素变为 0 0 0 。因此,输出为 − 1 -1 −1 。
题意
给你一个数组
a
a
a
你可以对数组
a
a
a 做一种操作:选择一个数字
x
x
x,使a中的所有元素变成 a与x的差的绝对值
问:能否通过不超过
40
40
40 次操作,使数组的所有元素变成
0
0
0
题解
看到 40
这个数字,有没有什么感觉
刚刚好没有超过 32
啊(联想一下 2^32
)
那是不是可以二分呢??我们再看看
假如说一个我选择一个数
x
x
x ,使所有数字变成
∣
a
i
−
x
∣
|a_i - x|
∣ai−x∣
那么我们可以看得出来,只要
a
i
≤
x
×
2
a_i \le x \times 2
ai≤x×2
就能得到:
∣
a
i
−
x
∣
≤
x
|a_i - x| \le x
∣ai−x∣≤x
即使最初的这个数很大很大(甚至
1
×
1
0
9
1 \times 10^9
1×109 )
我也能一层一层二分给他削减下去,直到最后为
0
0
0
**注:**因为数字不能超过
1
×
1
0
9
1 \times 10^9
1×109,所以我们只能从
2
30
2^{30}
230 开始往下减
第二个问题:怎么确认一个数组里面全部数字能不能变成
0
0
0 ?
已知:
- 奇数相减/偶数相减 得到的只会是偶数
- 奇偶相减 得到的只会是奇数
我们来对比一下:
- 奇数
- 和奇数相减 偶数
- 和偶数相减 奇数
- 偶数
- 和奇数相减 奇数
- 和偶数相减 偶数
我们可以看到
- 不管是奇数还是偶数,和奇数相减,奇偶性改变
- 不管是奇数还是偶数,和偶数相减,奇偶性不变
也就是说,不管我怎么操作,他们的奇偶性相对而言都是不变的
而最后我们要全部变成0
说明奇偶性要一致
所以我们只要判断是不是全部是奇数或者偶数就可以了
- 是,就可以全部变成0
- 不是,就不可以
PS:
从这里我们又能看到,因为
2
2
2 的任意次方都是偶数,没有改变奇偶性(
0
0
0 次方除外)
所以假如数组全部是偶数的话,减去一个
1
1
1 之后奇偶性改变,要再减去一个
1
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;
}
转载自博客https://www.cnblogs.com/jiejiejiang2004/p/18336168
博主已同意,我就是博主