0
点赞
收藏
分享

微信扫一扫

Codeforces Round #767 (Div. 2) A B C D E 题解

jjt二向箔 2022-01-23 阅读 68

A. Download More RAM

题目链接

  • https://codeforces.com/contest/1629/problem/A

题目大意

分析

  • 不难想到,贪心地将所有可行方案都选上
  • 可以提前排序进行,也可以 O ( n 2 ) O(n^2) O(n2)遍历选择

代码

#include<cstdio>
#include<algorithm>
#include<cstring>
#include<iostream>
#include<cmath>
#include<map>
#include<vector>
#include<queue>
#include<stack>
#include<string>
#include<ctime>
#include<list>
#include<ctime>
#define ll long long
using namespace std;
#define max(a,b) (a>b?a:b)
#define min(a,b) (a<b?a:b)
const int mo=998244353;
const int maxn=100010;
int n,k,t;
struct point{
	int a,b;
}p[maxn]; 

bool cmp(point a,point b){return a.a<b.a;}

int main(){
	cin>>t;
	while(t--){
		cin>>n>>k;
		for(int i=1;i<=n;i++) cin>>p[i].a;
		for(int i=1;i<=n;i++) cin>>p[i].b;
		sort(p+1,p+1+n,cmp);
		for(int i=1;i<=n;i++) if(p[i].a<=k) k+=p[i].b;
		cout<<k<<endl;
	}
}

B. GCD Arrays

题目链接

  • https://codeforces.com/contest/1629/problem/B

题目大意

分析

  • g c d > 1 ⇔ gcd > 1\Leftrightarrow gcd>1所有数都有一个不为 1 1 1的公因数
  • 显然这个公因数是 2 2 2最合适
  • 本题转化为 k k k次机会,将偶数乘到奇数上

代码

#include<cstdio>
#include<algorithm>
#include<cstring>
#include<iostream>
#include<cmath>
#include<map>
#include<vector>
#include<queue>
#include<stack>
#include<string>
#include<ctime>
#include<list>
#include<ctime>
#define ll long long
using namespace std;
const int mo=998244353;
const int maxn=2e5+10;
int n,t,a[maxn],b[maxn],cnt,to[maxn];
vector<int> pos[maxn];

int main(){
	cin>>t;
	while(t--){
		cin>>n;
		cnt=0;
		for(int i=0;i<=n;i++) pos[i].clear();
		memset(to,0,sizeof(to));
		for(int i=1;i<=n;i++){
			cin>>a[i];
			pos[a[i]].push_back(i);
		}
		int stp=0,st;
		while(stp<n){
			stp++;
			for(int i=0;;i++){
				while(to[i]<pos[i].size() && pos[i][to[i]]<stp){
					to[i]++;	
				}
				if(to[i]==pos[i].size()) {
					b[++cnt]=i;
					for(int j=0;j<i;j++) 
						stp=max(stp,pos[j][to[j]]);
					break;
				}
			}
		}
		cout<<cnt<<endl;
		for(int i=1;i<=cnt;i++) cout<<b[i]<<' ';cout<<endl;
	}
}

D. Peculiar Movie Preferences

题目链接

  • https://codeforces.com/contest/1629/problem/D

题目大意

分析

  • 如果长度是 1 1 1,本身就是回文串
  • 如果长度是 2 2 2
    • 两个字符相同是回文串
    • 可以和长度为 2 2 2的相反字符组成回文串
  • 如果长度是 3 3 3
    • 第一个和第三个字符相同就是回文串
    • 可以和长度为 3 3 3的相反字符组成回文串
    • 可以和已经出现的长度为 2 2 2的,和本身 2 − 3 2-3 23字符组相反的字符串成回文串
    • 可以和没有出现的长度为 2 2 2的,和本身 1 − 2 1-2 12字符组相反的字符串成回文串

代码

#include<cstdio>
#include<algorithm>
#include<cstring>
#include<iostream>
#include<cmath>
#include<map>
#include<vector>
#include<queue>
#include<stack>
#include<string>
#include<ctime>
#include<list>
#include<ctime>
#define ll long long
using namespace std;
const int mo=998244353;
const int maxn=1e5+10;
int n,t;
string s[maxn];
map<string,int> mp,mpr;

int main(){
	cin>>t;
	while(t--){
		cin>>n;
		for(int i=1;i<=n;i++) cin>>s[i];
		int f=0;
		
		for(int i=1;i<=n;i++) 
			if(s[i].length()==1){
				f=1;
				break;
			}
		for(int i=1;i<=n;i++) 
			if(s[i].length()==2 && s[i][0]==s[i][1]){
				f=1;
				break;
			}
		for(int i=1;i<=n;i++) 
			if(s[i].length()==3 && s[i][0]==s[i][2]){
				f=1;
				break;
			}
		for(int i=1;i<=n;i++){
			mp[s[i]]=1;
			if(s[i].length()==2){
				string ss="";
				ss+=s[i][1];
				ss+=s[i][0];
				if(mp[ss] || mpr[s[i]]){
					f=1;
					break;
				}
			} else if(s[i].length()==3) {
				string s1="",s2="",s3="";
				s1+=s[i][2],s1+=s[i][1],s1+=s[i][0];
				s2+=s[i][2],s2+=s[i][1];
				s3+=s[i][1],s3+=s[i][0];
				mpr[s3]=1;
				if(mp[s1] || mp[s2]){
					f=1;
					break;
				}
			}
		}
		cout<<(f?"YES":"NO")<<endl;
		mp.clear();
		mpr.clear();
	}
}

E. Grid Xor

题目链接

  • https://codeforces.com/contest/1629/problem/E

题目大意

分析

  • 原问题等价于选取 B B B的一些元素,让 A A A所有元素出现奇数次
  • 题目保证一定有解,所以不妨尝试打表
  • 从第二行开始,看前一行对应位置,如果是偶数次,就选这个点
  • 发现永远可行,证明留坑

代码

#include<cstdio>
#include<algorithm>
#include<cstring>
#include<iostream>
#include<cmath>
#include<map>
#include<vector>
#include<queue>
#include<stack>
#include<string>
#include<ctime>
#include<list>
#include<ctime>
#define ll long long
using namespace std;
const int mo=998244353;
const int maxn=1e3+10;
int n,t,a[maxn][maxn],ans,num[maxn][maxn];

void choose(int x,int y){
	ans^=a[x][y];
	num[x-1][y]++;
	num[x+1][y]++;
	num[x][y-1]++;
	num[x][y+1]++; 
}

int main(){
	cin>>t;
	while(t--){
		cin>>n;
		for(int i=1;i<=n;i++) 
			for(int j=1;j<=n;j++) 
				cin>>a[i][j];
		memset(num,0,sizeof(num));
		ans=0;
		for(int i=2;i<=n;i++) 
			for(int j=1;j<=n;j++)
				if(num[i-1][j]%2==0)
					choose(i,j);
		cout<<ans<<endl;
	}
}
举报

相关推荐

0 条评论