Codeforces Round #829 (Div. 2)

A. Technical Support

题目大意:
判断每个问题(Q)是否被回答(A)。


根据题意判断即可,注意多个\(A\)可以对于一个\(Q\)

\(code:\)

#include <bits/stdc++.h>

using namespace std;

inline void _main(){
	int n;
	string s;
	cin>>n>>s;
	int ans=0;
	for(int i=0;i<s.size();++i){
		if(s[i]=='Q'){
			if(ans>=0) ans++;
			else ans=1;
		}
		else{
			ans--;
		}
	}
	if(ans>0) puts("No");
	else puts("Yes");
}

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

B. Kevin and Permutation

题目大意:

构造一个长度为\(n\)的排列,使其\(k = \min_{i=1}^{n-1}{|a_{i+1}-a_i|}\)最大。


不难发现(实在发现不了可以打表),\(k=\lfloor\frac{n}{2}\rfloor\),考虑构造一个满足条件的排列。

只需要保证相邻两项之差大于等于\(k\)即可。

\(code:\)

#include <bits/stdc++.h>

using namespace std;

inline void _main(){
	int n;
	static int vis[1000 + 5],a[1000 + 5];
	cin>>n;
	for(int i=1;i<=n;++i) vis[i]=0;
	int k=n/2;
	if(n%2==0){
		int l=k,r=n;
		for(int i=1;i<=k;++i) printf("%d %d ",l,r),l--,r--;
	}
	else{
		for(int i=1;i<=n;i+=k) if(!vis[i]) printf("%d ",i),vis[i]=1;
		for(int l=k;l>=2;--l)
			for(int i=l;i<=n;i+=k) if(!vis[i]) printf("%d ",i),vis[i]=1;
	}
	printf("\n");
}

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

C1. Make Nonzero Sum (easy version)

题目大意:给出一个包含\(1,-1\)的序列,分成若干段,第\(i\)\([l_i,r_i]\)的权值\(s_i\)为交替和\(a_{l_i} - a_{l_i+1} + a_{l_i+2} - a_{l_i+3} + \ldots \pm a_{r_i}\),使得\(s_i\)之和为\(0\),求划分方案。


不难发现,\(n\)为奇数无解。(因为对于一个区间长度\(len\),若\(len\)是偶数,则\(s_i\)取值也为偶,若\(len\)为奇数,则\(s_i\)取值也为奇,要使\(s_i\)之和等于\(0\),则必须有偶数个\(len\)为奇数)

题目对分成的段数没有要求,于是两项两项的考虑,若同号,则可以划分为一组,权值为\(0\),若异号,则分别划分成一组,两组权值和为\(0\)

\(code:\)

#include <bits/stdc++.h>

using namespace std;

const int MAX_N = 200000 + 5;

int n,a[MAX_N];

pair<int,int> ans[MAX_N];

inline void _main(){
	int tot=0;
	cin>>n;
	for(int i=1;i<=n;++i) cin>>a[i];
	if(n&1){
		puts("-1");
		return;
	}
	for(int i=1;i<=n;i+=2){
		if(a[i]*a[i+1]>0){
			ans[++tot]=make_pair(i,i+1);
		}
		else{
			ans[++tot]=make_pair(i,i);
			ans[++tot]=make_pair(i+1,i+1);
		}
	}
	sort(ans+1,ans+1+tot);
	printf("%d\n",tot);
	for(int i=1;i<=tot;++i) printf("%d %d\n",ans[i].first,ans[i].second);
}

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

C2. Make Nonzero Sum (hard version)

题目大意:给出一个包含\(1,0,-1\)的序列,分成若干段,第\(i\)\([l_i,r_i]\)的权值\(s_i\)为交替和\(a_{l_i} - a_{l_i+1} + a_{l_i+2} - a_{l_i+3} + \ldots \pm a_{r_i}\),使得\(s_i\)之和为\(0\),求划分方案。


考虑在\(C1\)的方法上进行修改。

发现\(0\)对于题目只有更换正负号的作用。

于是,对于\(sum=\sum a_i\),我们考虑\(sum<0\)的情况:发现将一个\(+(-1)\)变成\(-(-1)\)会使得\(sum+=2\)\(sum>0\)同理。

所以\(sum\)为奇数的时候,无解。

然后再处理\(|sum|\)\(+\)\(-\)的情况即可。

\(code:\)

#include <bits/stdc++.h>

using namespace std;

const int MAX_N = 200000 + 5;

int n,a[MAX_N];

pair<int,int> ans[MAX_N];

inline void _main(){
	int tot=0;
	cin>>n;
	int cnt=0;
	for(int i=1;i<=n;++i) cin>>a[i];
	for(int i=1;i<=n;++i) cnt+=(a[i]!=0);
	if(cnt&1){
		puts("-1");
		return;
	}
	int sum=0;
	for(int i=1;i<=n;++i) sum+=a[i];
	if(sum>=0){
		static bool vis[MAX_N];
		for(int i=1;i<=n;++i) vis[i]=0;
		for(int i=1;i<=n;++i){
			if(a[i]==1 && sum>0){
				if(i>1 && !vis[i-1]){
					ans[++tot]=make_pair(i-1,i);
					vis[i-1]=1,vis[i]=1;
					sum-=2;
				}
			}
		}
		for(int i=1;i<=n;++i){
			if(!vis[i]) ans[++tot]=make_pair(i,i);
		}
		sort(ans+1,ans+1+tot);
		printf("%d\n",tot);
		for(int i=1;i<=tot;++i) printf("%d %d\n",ans[i].first,ans[i].second);
	}
	else{
		static bool vis[MAX_N];
		for(int i=1;i<=n;++i) vis[i]=0;
		for(int i=1;i<=n;++i){
			if(a[i]==-1 && sum<0){
				if(i>1 && !vis[i-1]){
					ans[++tot]=make_pair(i-1,i);
					vis[i-1]=1,vis[i]=1;
					sum+=2;
				}
			}
		}
		for(int i=1;i<=n;++i){
			if(!vis[i]) ans[++tot]=make_pair(i,i);
		}
		sort(ans+1,ans+1+tot);
		printf("%d\n",tot);
		for(int i=1;i<=tot;++i) printf("%d %d\n",ans[i].first,ans[i].second);
	}
}

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

D. Factorial Divisibility

题面大意:给出一个长度为\(n\)的序列\(a_1,a_2,a_3,...,a_n\),求\(a_1!+a_2!+...+a_n!\)是否能被\(x!\)整除。


发现题目求的是\(\sum a_i!\),从\(a_{i-1}\)\(a_i\)需要\(i\)\(a_{i-1}\)相加,所以判断是否所有\(a_i\)能像\(2048\)那样变成\(a_n\)即可。

\(code:\)

#include <bits/stdc++.h>

using namespace std;

const int MAX_N = 500000 + 5;

int n,x,a[MAX_N],cnt[MAX_N];

int main(){
	cin>>n>>x;
	for(int i=1;i<=n;++i) cin>>a[i],cnt[a[i]]++;
	for(int i=1;i<x;++i) while(cnt[i]>=(i+1)) cnt[i+1]++,cnt[i]-=(i+1);
	bool flag=1;
	for(int i=1;i<x;++i) if(cnt[i]) flag=false;
	if(flag) puts("Yes");
	else puts("No");
	return 0;
}

E.

posted @ 2022-10-23 21:37  Thermalrays  阅读(173)  评论(1编辑  收藏  举报