码迷,mamicode.com
首页 > 其他好文 > 详细

Codeforces Round #682 (Div. 2) 题解(A-E)

时间:2020-11-21 11:55:12      阅读:6      评论:0      收藏:0      [点我收藏+]

标签:nbsp   vector   存在   class   方式   close   枚举   cond   cout   

技术图片

 

 

题意:构造一个长度为n的数组,使得每个子数组中所有元素的和能被这个子数组的长度整除

 

解题思路:显然,构造一个元素全部相同的数组即可满足要求

代码:

技术图片
#include<iostream>
#include<algorithm>
#include<vector>
#include<cstdio>
#include<cstring>
#include<cmath>
#include<queue>
#include<set>
#include<stack>
#include<map>
#define pb push_back
#define mp make_pair
#define fi first
#define se second
#define mul_mod(a,b,c) a=(a*b)%mod
#define add_mod(a,b,c) a=(a+b)%mod
using namespace std;
typedef long long ll;
const int maxn=2e5+10;
const int maxm=5e5+10;
const int inf=0x3f3f3f3f;
int q;
int n;
int main()
{
    scanf("%d",&q);
    while(q--){
        scanf("%d",&n);
        for(int i=1;i<=n;i++) cout<<1<<" ";
        cout<<endl;
    }
    return 0;
}
View Code

 

技术图片

 

 

 

题意:给出一个数组b,由数组b可以得到数组a(ai=2^bi,1<=i<=n),问a数组是否存在两个不想交的区间,区间和相等。

解题思路:由于a数组全是二次幂,通过二进制的性质可得,如果a数组都是互不相同的元素,不可能存在两个区间和相等(因为只有存在相同的二次幂才可能向上进位,进而与其他的二次幂相等)。所以只要判断b数组中是否存在一个元素出现两次即可。

代码:

技术图片
#include<iostream>
#include<algorithm>
#include<vector>
#include<cstdio>
#include<cstring>
#include<cmath>
#include<queue>
#include<set>
#include<stack>
#include<map>
#define pb push_back
#define mp make_pair
#define fi first
#define se second
#define mul_mod(a,b,c) a=(a*b)%mod
#define add_mod(a,b,c) a=(a+b)%mod
using namespace std;
typedef long long ll;
const int maxn=2e5+10;
const int maxm=5e5+10;
const int inf=0x3f3f3f3f;
int q,n;
int main()
{
    scanf("%d",&q);
    while(q--){
        scanf("%d",&n);
        map<int,int> ma;
        int flag=0;
        for(int i=1;i<=n;i++){
            int t;
            scanf("%d",&t);
            if(ma[t]) flag=1;
            else ma[t]=1;
        }
        if(flag) puts("YES");
        else puts("NO");
    }
    return 0;
}
View Code

技术图片

 

 

 

题意:给出一个n*m的矩阵,问是否能对其中若干元素加1,使得没有两个相邻元素相等。

解题思路:可以通过下图所示的黑白棋盘得到启发,因为奇偶性不同的数字必然不等,可以通过给元素加1来改变元素的奇偶性,将整个矩阵分成奇数和偶数两种(类比于棋盘的黑白两色)

技术图片

 

 

 代码:

技术图片
#include<iostream>
#include<algorithm>
#include<vector>
#include<cstdio>
#include<cstring>
#include<cmath>
#include<queue>
#include<set>
#include<stack>
#include<map>
#define pb push_back
#define mp make_pair
#define fi first
#define se second
#define mul_mod(a,b,c) a=(a*b)%mod
#define add_mod(a,b,c) a=(a+b)%mod
using namespace std;
typedef long long ll;
const int maxn=1e2+10;
const int maxm=5e5+10;
const int inf=0x3f3f3f3f;
int q,n,m,t;
int main()
{
    scanf("%d",&q);
    while(q--){
        scanf("%d%d",&n,&m);
        for(int i=1;i<=n;i++){
            for(int j=1;j<=m;j++){
                scanf("%d",&t);
                if((i+j)%2==t%2)  t++;
                cout<<t<<" ";
            }
            cout<<endl;
        }
    }
    return 0;
}
View Code

技术图片

 

 

 

 

题意:给出一个数组,可以将数组中三个元素的值同时变成三个元素的异或(ai=aj=ak=(ai^aj^ak)。问能否在n步操作内将数组变成全部相等的元素,能的话请给出操作步数以及具体步骤。

解题思路:

  通过观察能够发现以下两个特性:

  1. ax^ax^ay=ay  即两个相同的元素与第三个元素进行异会得到第三个元素

  2. a1^a2^a3=p1   p1^p1^p1=p1  => 操作前后三个元素的异或得到的值不会改变

  我们先考虑当n为奇数的情况:

 

a1 a2 a3 a4 a5 a6 a7
p1 p1 p1 a4 a5 a6 a7
p1 p1 p2 p2 p2 a6 a7
p1 p1 p2 p2 p3 p3 p3

 

  其中:  p1=a1^a2^a3      p2=a3^a4^a5     p3=a5^a6^a7 

  于是可以根据第一个特性分别将两个p1、p2与p3进行异或,使得全部等于p3

  同理,所有n为奇数的情况都可以通过上述操作步骤使得数组元素全部相等

  我们再来考虑n为偶数的情况:

  首先,根据第二个特性可知整个数组的异或和是不会随着操作改变的,而我们又能清楚最终的结果是元素全部相等,再加上n为偶数,可以得到以下结论:

  如果存在操作能够使得元素全部相等,那么数组的异或和必为0。

  如果不为0,则无论如何都不可能使得数组内全部相等。

  所以可以在一开始把全部元素异或一遍,如果不为0,直接输出NO

  如果为0,将前面n-1个元素按照n为奇数的处理方式处理一遍,将前面n-1个元素都变成相同的。

  由于整体异或和为0,所以此时最后一个元素也和前面n-1个元素相等,即全部元素相等,操作完毕。

     

代码:

技术图片
#include<iostream>
#include<algorithm>
#include<vector>
#include<cstdio>
#include<cstring>
#include<cmath>
#include<queue>
#include<set>
#include<stack>
#include<map>
#define pb push_back
#define mp make_pair
#define fi first
#define se second
#define mul_mod(a,b,c) a=(a*b)%mod
#define add_mod(a,b,c) a=(a+b)%mod
using namespace std;
typedef long long ll;
const int maxn=1e5+10;
const int maxm=5e5+10;
const int inf=0x3f3f3f3f;
int n;
int a[maxn];
void solveAdd(int n){
    puts("YES");
    printf("%d\n",n-2);
    for(int i=1;i<n;i+=2) printf("%d %d %d\n",i,i+1,i+2);
    for(int i=1;i<n-2;i+=2) printf("%d %d %d\n",i,i+1,n);
}
void solveEven(int n){
    int sum=0;
    for(int i=1;i<=n;i++) sum^=a[i];
    if(sum){
        puts("NO");
        return;
    }
    solveAdd(n-1);
}
int main()
{
    scanf("%d",&n);
    for(int i=1;i<=n;i++) scanf("%d",&a[i]);
    if(n%2) solveAdd(n);
    else solveEven(n);
    return 0;
}
View Code

技术图片

 

 

 

题意:给定一个长度为n(3<=n<=2e5)的数组,问存在多少个长度至少为3区间[l,r],满足a[l]^a[r]=(a[l+1]+a[l+2]+...+a[r-1])

 

解题思路:通过左右两端点的值来给限定最大值,假设k是a[l]和a[r]中二进制的最高位,则最大值设为1<<(k+1),

很显然a[l]^a[r]< 1<<(k+1)。通过正反遍历两遍,枚举左右端点,遇到满足的就存入set数组,存入set数组是为了避免重复计算。

时间复杂度为什么是O(2*n*log(Maxa[i]))我还是没懂,证明不了,等到啥时候懂了再补上

代码:

技术图片
#include<iostream>
#include<algorithm>
#include<vector>
#include<cstdio>
#include<cstring>
#include<cmath>
#include<queue>
#include<set>
#include<stack>
#include<map>
#define pb push_back
#define mp make_pair
#define fi first
#define se second
#define mul_mod(a,b,c) a=(a*b)%mod
#define add_mod(a,b,c) a=(a+b)%mod
using namespace std;
typedef long long ll;
const int maxn=2e5+10;
const int maxm=5e5+10;
const int inf=0x3f3f3f3f;
int n;
int a[maxn];
set<ll> se;
int getMax(int x){
    for(int i=1<<30;i;i>>=1){
        if(x&i) return i<<1;
    }
}
int main()
{

    scanf("%d",&n);
    for(int i=1;i<=n;i++) scanf("%d",&a[i]);
    for(int l=1;l<n-1;l++){
        ll sum=a[l+1];
        int k=getMax(a[l]);
        for(int r=l+2;r<=n&&sum<=k;r++){
            if((a[l]^a[r])==sum)        se.insert((ll)l*maxn+r);
            sum+=a[r]; 
        }
    }
    for(int r=n;r>=3;r--){
        ll sum=a[r-1];
        int k=getMax(a[r]);
        for(int l=r-2;l>=1&&sum<=k;l--){
            if((a[l]^a[r])==sum)    se.insert((ll)l*maxn+r);
            sum+=a[l];
        }
    }
    cout<<se.size()<<endl;
    return 0;
}
View Code

 

Codeforces Round #682 (Div. 2) 题解(A-E)

标签:nbsp   vector   存在   class   方式   close   枚举   cond   cout   

原文地址:https://www.cnblogs.com/Momo-zzz/p/13992099.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!