Codeforces Round #803 (Div. 2)个人题解

这篇博客解析了三道来自Codeforces比赛的题目:A.XOR Mixup通过暴力求解XOR,B.Rising Sand分析1和k操作对沙堆的影响,C.3SUM Closure判断数组的3SUM封闭性质。博主Mzx分享了详细思路和代码实现。
摘要由CSDN通过智能技术生成

@[TOC](Codeforces Round #803 (Div. 2) 个人题解)

A. XOR Mixup

在这里插入图片描述
在这里插入图片描述
题意:
有一个有n-1个整数的数组a。让x是数组中所有元素的位XOR。数字x被加到数组a的末尾(现在它的长度为n),然后元素被洗牌。
给你新形成的数组a,x是什么?如果x有多个可能的值,你可以输出其中任何一个。

思路:
数据范围比较小,直接暴力for循环即可。

/*
 author : Mzx
*/
#include<bits/stdc++.h>

using namespace std;

typedef long long ll;
typedef long double ld;
typedef pair<int,int> PII;
const ll mod=1e9+7;
const int INF=0x3f3f3f3f;
const int maxn=1e5+10;
#define ios ios::sync_with_stdio(false);cin.tie(0);cout.tie(0);
#define x first
#define y second


int read () {
    int k=0,f=1;
    char c=getchar ();
    while (c<'0'||c>'9') {if (c=='-') f=-1;c=getchar ();}
    while (c>='0'&&c<='9') {k=k*10+c-'0';c=getchar ();}
    return k*f;
}

int a[110];

void solve()
{
    int n;cin>>n;
    for(int i = 1;i<=n;i++) cin>>a[i];

    int ans = 0;
    for(int i = 1;i <= n;i ++)
    {
        int temp = 0;
        for(int j = 1;j <= n;j++)
        {
            if(j == i) continue;
            temp = temp^a[j];
            //cout<<temp<<endl;
        }
        if(temp == a[i]) {
            ans = a[i];
            break;
        }
    }
    cout<<ans<<endl;
}


int main()
{
    ios;
    int t; cin>>t;
    while(t--)
    {
        solve();
    }
    return 0;
}

“注意,0^x=x”

B. Rising Sand

在这里插入图片描述
在这里插入图片描述

题意:
有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。

思路:
如果k>1,那么无论怎么选择,该数和左边或者右边的数都会增加,所以对答案无意义。
如果k=1,那么我们需要找出数量最多的”太高沙堆“,我们用X表示不为“太高沙堆”的沙堆,用√表示“太高沙堆”,一个√的左右两个沙堆均为X,并且第一个和最后一个都为X,所以把最后一个先忽略,我们就能得到X√X√X√。。。的序列,故√的最大数量为(n - 1)/2;

/*
 author : Mzx
*/
#include<bits/stdc++.h>

using namespace std;

typedef long long ll;
typedef long double ld;
typedef pair<int,int> PII;
const ll mod=1e9+7;
const int INF=0x3f3f3f3f;
const int maxn = 2e5+10;
#define ios ios::sync_with_stdio(false);cin.tie(0);cout.tie(0);
#define x first
#define y second


int read () {
    int k=0,f=1;
    char c=getchar ();
    while (c<'0'||c>'9') {if (c=='-') f=-1;c=getchar ();}
    while (c>='0'&&c<='9') {k=k*10+c-'0';c=getchar ();}
    return k*f;
}

int a[maxn];

void solve() {
    int n, k; cin >> n >> k;
    for (int i = 1; i <= n; i++) cin >> a[i];

    int ans = 0;
    if (k == 1) ans = (n - 1) / 2;
    else{   
        for (int i = 2; i < n; i++) {
            if (a[i - 1] + a[i + 1] < a[i]) ans++;
        }
    }
    cout<<ans<<endl;
}


int main()
{
    ios;
    int t; cin>>t;
    while(t--)
    {
        solve();
    }
    return 0;
}

C. 3SUM Closure

在这里插入图片描述
在这里插入图片描述
题意:
如果对于所有不同的指数i,j,k,总和ai+aj+ak是数组中的一个元素,则该数组被称为3SUM封闭。更正式地说,如果对于所有整数1≤i<j<k≤n,存在一些整数1≤l≤n,使得ai+aj+ak=al,则a是3SUM封闭的。

判断a是否是3SUM封闭的。

思路:
根据样例,n<6时直接暴力循环即可,n>=6时,必须满足排序之后从第二个到第n-1个均为0,第一个和最后一个的和在数组内部才符合条件。

/*
 author : Mzx
*/
#include<bits/stdc++.h>

using namespace std;

typedef long long ll;
typedef long double ld;
typedef pair<int,int> PII;
const ll mod=1e9+7;
const int INF=0x3f3f3f3f;
const int maxn = 2e5+10;
#define ios ios::sync_with_stdio(false);cin.tie(0);cout.tie(0);
#define x first
#define y second


int read () {
    int k=0,f=1;
    char c=getchar ();
    while (c<'0'||c>'9') {if (c=='-') f=-1;c=getchar ();}
    while (c>='0'&&c<='9') {k=k*10+c-'0';c=getchar ();}
    return k*f;
}

int a[maxn];
set<int> p;

void solve() {
    p.clear();
    int n;cin>>n;
    for(int i = 1;i<=n;i++) cin>>a[i];
    sort(a+1,a+1+n);
    if(n >= 6)
    {
        p.insert(a[1]);
        p.insert(0);
        p.insert(a[n]);
        if(p.count(a[1]+a[n]) && a[2] == 0 && a[n - 1] == 0)
            cout<<"Yes"<<endl;
        else
            cout<<"No"<<endl;
    }else {
        bool ok = true;
        for (int i = 1; i <= n; i++) {
            for (int j = i + 1; j <= n; j++) {
                for (int k = j + 1; k <= n; k++) {
                    int num = lower_bound(a + 1, a + 1 + n, a[i] + a[j] + a[k]) - a;
                    if (a[num] != (a[i] + a[j] + a[k])) ok = false;
                }
            }
        }
        if(ok) cout<<"Yes"<<endl;
        else cout<<"No"<<endl;
    }
}


int main()
{
    ios;
    int t; cin>>t;
    while(t--)
    {
        solve();
    }
    return 0;
}
  • 8
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值