题解:Pinely Round 4 (Div. 1 + Div. 2) C

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

在一次操作中,您将执行以下两步移动:

  1. 选择一个整数 x x x ( 0 ≤ x ≤ 1 0 9 0 \le x \le 10^{9} 0x109 )。
  2. 将每个 a i a_i ai 替换为 ∣ a i − x ∣ |a_i - x| aix ,其中 ∣ 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] [58,78,108]=[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 1t104 )–测试用例数。( 1 ≤ t ≤ 1 0 4 1 \le t \le 10^4 1t104 )–测试用例的数量。测试用例说明如下。

每个测试用例的第一行都包含一个整数 n n n ( 1 ≤ n ≤ 2 ⋅ 1 0 5 1 \le n \le 2 \cdot 10^5 1n2105 ) - 数组 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 0ai109 ) - 数组 a a a 的元素。

保证所有测试用例中 n n n 的总和不超过 2 ⋅ 1 0 5 2 \cdot 10^5 2105

Output

对于每个测试用例,如果不可能在最多 40 40 40 次操作中使所有数组元素等于 0 0 0 ,则输出一个整数 − 1 -1 1

否则,输出两行。第一行输出应包含一个整数 k k k ( 0 ≤ k ≤ 40 0 \le k \le 40 0k40 ) - 运算次数。第二行输出应该包含 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} 0xi109 ) - 运算序列,表示在 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| aix
那么我们可以看得出来,只要 a i ≤ x × 2 a_i \le x \times 2 aix×2
就能得到: ∣ a i − x ∣ ≤ x |a_i - x| \le x aixx
即使最初的这个数很大很大(甚至 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
博主已同意,我就是博主

  • 5
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值