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

A

题意
给定一个 n n n,构造一个长度为 n n n的数组 a a a,满足:1. a a a的任意子数组的和均能被其长度整除;2. 1 ≤ a i ≤ 100 1 \le {a_i} \le 100 1ai100
思路
方法很多,直接输出长度为 n n n的全1数组即可。
代码

#include<bits/stdc++.h>
#define FULL(x,y) memset(x,y,sizeof(x))
#define ll long long
#define pb push_back
using namespace std;

int t,n;

int main() {
	cin>>t;
	while(t--) {
		cin>>n;
		for(int i=1;i<=n;i++) cout<<1<<' ';
		cout<<endl;
	}
	return 0;
}

B

题意
给定一个长度为 n n n的数组 b b b,另有一数组 a a a满足 a i = 2 b i ( 1 ≤ i ≤ n ) {a_i} = {2^{{b_i}}}(1 \le i \le n) ai=2bi(1in),判断是否存在不相交的两段子数组 [ l 1 , r 1 ] \left[ {{l_1},{r_1}} \right] [l1,r1] [ l 2 , r 2 ] \left[ {{l_2},{r_2}} \right] [l2,r2],满足 ∑ i = l 1 r 1 a i = ∑ i = l 2 r 2 a i \sum\limits_{i = {l_1}}^{{r_1}} {{a_i} = } \sum\limits_{i = {l_2}}^{{r_2}} {{a_i}} i=l1r1ai=i=l2r2ai
思路
只有当 b b b数组中的元素互不相同的时候就不存在满足要求的两段子数组。
代码

#include<bits/stdc++.h>
#define FULL(x,y) memset(x,y,sizeof(x))
#define ll long long
#define pb push_back
using namespace std;
 
const int N=1005;
int t,n;
int b[N];
 
int main() {
	cin>>t;
	while(t--) {
		cin>>n;
		unordered_map<int,int> um;
		for(int i=1;i<=n;i++) {
			cin>>b[i];
			um[b[i]]++;
		}
		int fl=0;
		for(int i=1;i<=n;i++) {
			if (um[b[i]]>1) {
				fl=1;
				cout<<"YES"<<endl;
				break;
			}
		}
		if (!fl) cout<<"NO"<<endl;
	}
	return 0;
}

C

题意
给定一个 n × m n \times m n×m的矩阵 a a a,将矩阵中的某些元素加1,构造出一个使所有相邻元素不同的矩阵,可以证明这样的矩阵一定存在。
思路
将这个矩阵的数交错奇偶排列,不满足要求修改当前的值即可。
代码

#include<bits/stdc++.h>
#define FULL(x,y) memset(x,y,sizeof(x))
#define ll long long
#define pb push_back
using namespace std;

const int N=105;
int t,n,m;
int a[N][N];

int main() {
	cin>>t;
	while(t--) {
		cin>>n>>m;
		for(int i=1;i<=n;i++) {
			for(int j=1;j<=m;j++) {
				cin>>a[i][j];
			}
		}
		for(int i=1;i<=n;i++) {
			for(int j=1;j<=m;j++) {
				if (i&1) {
					if (j&1 && a[i][j]%2==0) a[i][j]++;
					if (j%2==0 && a[i][j]&1) a[i][j]++;
					cout<<a[i][j]<<' '; 
				}
				else {
					if (j&1 && a[i][j]%2!=0) a[i][j]++;
					if (j%2==0 && a[i][j]%2==0) a[i][j]++;
					cout<<a[i][j]<<' '; 
				}
			}
			cout<<endl;
		}
	}
	return 0;
}

D

题意
给定一个包含 n n n个正整数的数组 a a a,每次操作可以选择其中三个不同的整数 a i {a_i} ai a j {a_j} aj a k {a_k} ak,将这三个整数的值变为 a i ⊕ a j ⊕ a k {a_i} \oplus {a_j} \oplus {a_k} aiajak,即三个数的异或,问是否在不超过 n n n次的操作下能将数组所有的数变为相等。
思路
假如有5个数, { a 1 , a 2 , a 3 , a 4 , a 5 } \{ {a_1},{a_2},{a_3},{a_4},{a_5}\} {a1,a2,a3,a4,a5},考虑将前3个数做一次操作,数组变为 { b , b , b , a 4 , a 5 } \{ b,b,b,{a_4},{a_5}\} {b,b,b,a4,a5},再对第3、4、5位置的数做一次操作,数组变为 { b , b , c , c , c } \{ b,b,c,c,c\} {b,b,c,c,c},根据异或的性质, a ⊕ b ⊕ b = a a \oplus b \oplus b = a abb=a,再往前推,选择1、2、3位置的数操作,即可将数组变为相等。注意,这种方法的总操作次数为 n − 2 n-2 n2,且必须满足 n n n为奇数;当 n n n为偶数的时候,整体考虑要通过异或使数组所有数相等,那么数组所有数的异或和应该为0,所以 n n n为偶数时,若数组所有数异或和不为0,就不能通过这种操作使所有数相等,反之只需对前 n − 1 n-1 n1个数进行操作,这样最后前 n − 1 n-1 n1个数的值一定会和最后一个数相等。
代码

#include<bits/stdc++.h>
#define FULL(x,y) memset(x,y,sizeof(x))
#define ll long long
#define pb push_back
using namespace std;
 
int n;
int a[100005];
 
int main() {
	cin>>n;
	int ans=0;
	for(int i=1;i<=n;i++) {
		cin>>a[i];
		ans^=a[i];
	}
	if (n&1 || (n%2==0 && !ans)) {
		cout<<"YES"<<endl;
		if (n%2==0) n--;
		cout<<n-2<<endl;
		for(int i=1;i+2<=n;i+=2) {
			cout<<i<<' '<<i+1<<' '<<i+2<<endl;
		}
		for(int i=n-2;i-2>=1;i-=2) {
			cout<<i<<' '<<i-1<<' '<<i-2<<endl;
		}
	}
	else {
		cout<<"NO"<<endl;
	}
	return 0;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值