codeforces#803(Div2) A-C

Problem - A - Codeforces

A. XOR Mixup

There is an array a with n−1 integers. Let x be the bitwise XOR of all elements of the array. The number x is added to the end of the array a (now it has length n), and then the elements are shuffled.

You are given the newly formed array a. What is x? If there are multiple possible values of x, you can output any of them.

Input

The input consists of multiple test cases. The first line contains an integer t (1≤t≤1000) — the number of test cases. The description of the test cases follows.

The first line of each test case contains an integer n (2≤n≤100) — the number of integers in the resulting array a.

The second line of each test case contains n integers a1,a2,…,an(0≤ai≤127) — the elements of the newly formed array a.

Additional constraint on the input: the array a is made by the process described in the statement; that is, some value of x exists.

Output

For each test case, output a single integer — the value of x, as described in the statement. If there are multiple possible values of x, output any of them.

———————————————————————————————————————————

有一个数组 a 具有 n−1 个整数。设 x 是数组中所有元素的按位异或。数字 x 被添加到数组 a 的末尾(现在它具有长度 n),然后对元素进行随机排序。

您将获得新形成的数组 a。什么是 x?如果 x 有多个可能的值,则可以输出其中任何一个值。

输入的附加约束:数组a由语句中描述的过程构成;也就是说,x 的某些值存在。

对于每个测试用例,输出一个整数 — x 的值,如语句中所述。如果 x 有多个可能的值,请输出其中任何一个值。

———————————————————————————————————————————

题解:由题意知,x=a1^a2^a3^...^an-1,x被添入队尾后数组变成a1,a2,...,an-1,x,然后数组顺序被随机打乱,我们要找到谁可以是数组中的那个x。我们知道按位异或相同为0,不同为1,所以很明显两个相同的数的按位异或是0。我们假设第一个数是可以由剩下n-1个数按位异或得来的,分两种情况,第一种数组打乱顺序后x直接处在了第一个位置,显然直接成立;第二种是第一个数虽然不是x,但它是剩下n-1个数的按位异或,也符合题意,那么证明如下  a1=a2^a3^...^an  -1^x=a2^a3^...^an-1^a1^a2^a3^...^an-1=a1,我们再只需要思考此时x还会是它们的按位异或了吗,如果是证明就成立,x=a1^a2^a3^...^an-1=a2^a3^...^an  -1^x^a2^a3^...^an-1=x,成立。

其实以此类推,数组中每一个数都符合题意,随便输出哪个都行。

#include<iostream>
using namespace std;
int a[100];
int main(){
    int t,n,i;
    cin>>t;
    while(t--){
        cin>>n;
        for(i=0;i<n;i++){
            cin>>a[i];
        }
        cout<<a[0]<<endl;
    }
    return 0;
}

Problem - B - Codeforces

B. Rising Sand

There are n piles of sand where the i-th pile has ai blocks of sand. The i-th pile is called too tall if 1<i<n and ai>ai−1+ai+1. That is, a pile is too tall if it has more sand than its two neighbours combined. (Note that piles on the ends of the array cannot be too tall.)

You are given an integer k. An operation consists of picking k consecutive piles of sand and adding one unit of sand to them all. Formally, pick 1≤l,r≤n such that r−l+1=k. Then for all l≤i≤r, update ai←ai+1.

What is the maximum number of piles that can simultaneously be too tall after some (possibly zero) operations?

Input

The input consists of multiple test cases. The first line contains an integer t (1≤t≤1000) — the number of test cases. The description of the test cases follows.

The first line of each test case contains two integers n and k (3≤n≤2⋅105; 1≤k≤n) — the number of piles of sand and the size of the operation, respectively.

The second line of each test case contains n integers a1,a2,…,an (1≤ai≤109) — the sizes of the piles.

It is guaranteed that the sum of n over all test cases does not exceed 2⋅105.

Output

For each test case, output a single integer — the maximum number of piles that are simultaneously too tall after some (possibly zero) operations.

input

3
5 2
2 9 2 4 1
4 4
1 3 2 1
3 1
1 3 1

output

2
0
1

——————————————————————————————————————————

有n堆沙子,其中第i堆有ai沙块。如果 1<i<n 和 ai>ai−1+ai+1,则第 i 堆称为太高。也就是说,如果一堆沙子的沙子比两个邻居的总和还要多,那么它就太高了。(请注意,数组两端的堆积不能太高。

您将获得一个整数 k。一个操作包括选择k个连续的沙堆,并向它们添加一个单位的沙子。形式上,选择 1≤l,r≤n,使得 r−l+1=k。然后,对于所有 l≤i≤r,更新 ai←ai+1。

在一些(可能为零)操作后,同时可能太高的最大桩数是多少?

——————————————————————————————————————————

题解:沙堆太高指的是ai>ai−1+ai+1,很容易发现,如果k=1,那么就是只有它自己可以升高,如果k大于1,那么它的邻居也同样会升高,最终结果还是原来的状态。(首尾不能是过高的沙堆)

#include<iostream>
using namespace std;
#define ll long long
int a[200005];
int main(){
    int t,n,i,k;
    cin>>t;
    while(t--){
        cin>>n>>k;
        for(i=1;i<=n;i++){
            cin>>a[i];
        }
        if(k==1){
            cout<<(n-1)/2<<endl;
            continue;
        }
        int sum=0;
        //统计一开始有多少个过高的沙堆
        for(i=2;i<=n-1;i++){
            ll t=a[i-1]+a[i+1];
            if(a[i]>t){
                sum++;
            }
        }
        cout<<sum<<endl;
    }
    return 0;
}

Problem - C - Codeforces

C. 3SUM Closure

You are given an array a of length n. The array is called 3SUM-closed if for all distinct indices i, j, k, the sum ai+aj+ak is an element of the array. More formally, a is 3SUM-closed if for all integers 1≤i<j<k≤n, there exists some integer 1≤l≤n such that ai+aj+ak=al.

Determine if a is 3SUM-closed.

Input

The first line contains an integer t (1≤t≤1000) — the number of test cases.

The first line of each test case contains an integer n (3≤n≤2⋅105) — the length of the array.

The second line of each test case contains n integers a1,a2,…,an (−109≤ai≤109) — the elements of the array.

It is guaranteed that the sum of n across all test cases does not exceed 2⋅105.

Output

For each test case, output "YES" (without quotes) if a is 3SUM-closed and "NO" (without quotes) otherwise.

You can output "YES" and "NO" in any case (for example, strings "yEs", "yes" and "Yes" will be recognized as a positive response).

input

4
3
-1 0 1
5
1 -2 -2 1 -3
6
0 0 0 0 0 0
4
-1 2 -3 4

output

YES
NO
YES
NO

In the first test case, there is only one triple where i=1, j=2, k=3. In this case, a1+a2+a3=0, which is an element of the array (a2=0), so the array is 3SUM-closed.

In the second test case, a1+a4+a5=−1, which is not an element of the array. Therefore, the array is not 3SUM-closed.

In the third test case, ai+aj+ak=0 for all distinct i, j, k, and 0 is an element of the array, so the array is 3SUM-closed.

———————————————————————————————————————————

您将获得一个长度为 n 的数组 a。如果对于所有不同的索引 i、j、k,总和 ai+aj+ak 是数组的一个元素,则该数组称为 3SUM 闭合。更正式地说,如果对于所有整数 1≤i<j<k≤n,则 a 是 3SUM 闭合的,存在一些整数 1≤l≤n,使得 ai+aj+ak=al。

确定 是否为 3SUM 闭合。

———————————————————————————————————————————

题解:首先我们选取数组中最大的三个正数,那么它们三个的和一定比自身都要大,也就是和一定不会在数组里,所以数组中不可能会出现3个正数,正数至多2个。

同理,选取三个最小的负数,那么它们三个的和一定比自身都要小,也就是和一定不会在数组里,所以数组中不可能会出现3个负数,负数至多2个。

最后还剩下0没有讨论,如果数组中有0,那么至少要放一个0进去,因为有可能有三数之和为0,或者其中一个数为0也对三数之和有影响,如果有两个0及以上,那么就没有必要再选了,因为如果只使用一个0就和选一个0是同样的效果,使用两个0得到的也是自己本身,没有必要讨论。即至多一个0。

所以数组最多5个数,直接暴力就可以了。

这里要注意:对于v.size()-2这些我们本来想的是得到一个负数,这样不满足循环条件就可以直接退出循环,可实际上运行时会发现对于6个0那个样例我们直接就超时了,后来调试发现i、j并没有退出循环,而是一直变大。这是因为通常情况下,数字都默认为有符号类型,v.size()这些STL中的函数返回值是size_t,也就是无符号数,而在有符号数和无符号数一起进行运算时有符号数会主动转化为无符号数,对于负数(-N)转换成无符号数是2^32-N,所以我们得到的是一个很大很大的数。所以导致最后暴力超时了。我们用一个变量存储它就可以解决这个问题了。

补充:两个无符号数的相减可理解为一正加一负,如果有符号数的结果为正,那么无符号数的结果与其相同,如果结果出现负数,但是无符号数本身取值范围是≥0的,所以无符号数会将运算结果的补码视为原码。

#include<iostream>
#include<vector>
using namespace std;
void solve() {
    int n, i, j, k, m, a;
    vector<int>v;
    int num = 0;
    cin >> n;
    for (i = 0; i < n; i++) {
        cin >> a;
        if ((a != 0) || (a == 0 && num < 1)) {
            v.push_back(a);
            if (a == 0)num++;
        }
    }
    if (v.size() > 5) {
        cout << "NO" << endl;
        return;
    }
    int x = v.size() - 2,y=v.size() - 1,z=v.size();
    for (i = 0; i < x; i++) {
        for (j = i + 1; j <y ; j++) {
            for (k = j + 1; k <z ; k++) {
                bool judge = 0;
                int sum = v[i] + v[j] + v[k];
                for (m = 0; m < v.size(); m++) {
                    if (v[m] == sum) {
                        judge = 1;
                        break;
                    }
                }
                if (!judge) {
                    cout << "NO" << endl;
                    return;
                }
            }
        }
    }
    cout << "YES" << endl;
}
int main() {
    ios::sync_with_stdio(false);
    cout.tie(0); cin.tie(0);
    int t;
    cin >> t;
    while (t--) {
        solve();
    }
    return 0;
}

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值