Codeforces Round 972 (Div. 2) A-C 题解

本来以为 B2 难度会 1900 什么的,结果感觉 1200 还没有,先做的 B1,后悔了 QwQ

关于我现场没切出 C 这件事…… 现场排名:

Codeforces Round 972 (Div. 2) A-C 题解_第1张图片

A. Simple Palindrome

题意

构造一个长度为 n n n 的字符串,只包含 a e i o u 五种字母,需要使得构造出来的字符串所包含的 回文 子序列 数量最小

思路

n ≤ 5 n\le 5 n5 时,只要 5 5 5 个字母不重复出现都是最优情况

n > 5 n > 5 n>5 时,可以证明:

  • 把相同字母放在一起是最优情况:若分开,可与中间任意一个字母组成回文串,而放在一起则不会
  • 尽量使需要重复的字母的数量 平均 是最优情况:自己举例即可,如 n = 7 n=7 n=7
C++ 代码
#include
using namespace std;
string str(int num,string t){
	string ret;
	while(num!=0){
		num--;
		ret+=t;
	}
	return ret;
}
void solve(){
	int n;
	cin>>n;
	int k=n/5; //向下取整
	string ans="";
	ans+=str(k,"a");
	if(n%5!=0) ans+='a',n--;
	ans+=str(k,"e");
	if(n%5!=0) ans+='e',n--;
	ans+=str(k,"i");
	if(n%5!=0) ans+='i',n--;
	ans+=str(k,"o");
	if(n%5!=0) ans+='o',n--;
	ans+=str(k,"u");
	if(n%5!=0) ans+='u',n--;
	cout<<ans<<endl;
}
int main(){
    int t;
	cin>>t;
	while(t--){
		solve();
	}
	return 0;
}

B1. The Strict Teacher (Easy Version)

题意

2 2 2 个老师分别在 b 1 , b 2 b_1,b_2 b1,b2,学生在 a 1 a_1 a1,每次老师和学生必须在 [ 1 , n ] [1,n] [1,n] 之间且必须为整数,要么不动要么移动一格,若双方都用最优策略,老师至少要多少秒才能抓到学生?

保证 b 1 ≠ b 2 b_1 \ne b_2 b1=b2 a 1 ≠ b 1 a_1 \ne b_1 a1=b1 a 1 ≠ b 2 a_1 \ne b_2 a1=b2

思路

b b b 排序 ( 1 ≤ b 1 < b 2 ≤ n ) (1 \le b_1 < b_2\le n) (1b1<b2n),分类讨论:

  • a 1 < b 1 a_1 < b_1 a1<b1,答案为 ( b 1 − k ) + ( k − 1 ) = b 1 − 1 (b_1-k)+(k-1) =b_1-1 (b1k)+(k1)=b11

  • b 1 < a 1 < b 2 b_1b1<a1<b2,答案为 ⌊ b 2 − b 1 2 ⌋ \displaystyle \lfloor \frac{b2-b1}2 \rfloor 2b2b1

  • a 1 > b 2 a_1>b_2 a1>b2,答案为 ( k − b 2 ) + ( n − k ) = n − b 2 (k-b_2)+(n-k)=n-b_2 (kb2)+(nk)=nb2

C++ 代码
#include
#define int long long
using namespace std;
void solve(){
	int n,m,q;
    int b1,b2;
    int k;
	cin>>n>>m>>q>>b1>>b2>>k;
    
	if(b1>b2){
		swap(b1,b2);
	}
    
	if(k>b1&&k<b2){
		cout<<(b2-b1)/2<<endl;
	}else if(k<b1){
		cout<<b1-1<<endl;
	}else{
		cout<<n-b2<<endl;
	}
}
signed main(){
	int t=1;
	cin>>t;
	while(t--){
		solve();
	}
	return 0;
}

B2. The Strict Teacher (Hard Version)

题意

m m m 个老师,第 i i i 个在 b i b_i bi q q q 个学生,第 j j j 个在 a j a_j aj,每次老师和学生必须在 [ 1 , n ] [1,n] [1,n] 之间且必须为整数,要么不动要么移动一格,若双方都用最优策略,那么对于每一名学生,老师抓到他至少要多少秒?

保证 b i b_i bi 互不相同,且 a j ≠ b i ( 1 ≤ i ≤ m ,   1 ≤ j ≤ q ) a_j \ne b_i (1\le i \le m,\ 1 \le j \le q) aj=bi(1im, 1jq)

思路

类似地,像 B1 一样,如何找到像 b 1 , b 2 b_1,b_2 b1,b2 一样的区间呢?

考虑 二分 出第一个大于 a j a_j aj b i b_i bi,并按照上述方法判断即可

C++ 代码
#include
#define int long long
using namespace std;
void solve(){
	int n,m,q;
	cin>>n>>m>>q;
	vector<int> b(m);
	for(int i=0;i<m;i++){
		cin>>b[i];
	}
	sort(b.begin(),b.end());
    
	while(q--){
		int k;
		cin>>k;
		int pos=upper_bound(b.begin(),b.end(),k)-b.begin();
		if(pos==0){
			cout<<b[0]-1<<endl;
		}else if(pos==m){
			cout<<n-b[m-1]<<endl;
		}else{
			cout<<(b[pos]-b[pos-1])/2<<endl;
		}
	}
}
signed main(){
    int t;
	cin>>t;
	while(t--){
		solve();
	}
	return 0;
}

C. Lazy Narek

题意

在所给的 n n n 个长度为 m m m 的字符串选择任意多个(可能是 0 0 0 个),不改变顺序拼接在一起,选择子序列narek,每选一个 Narek 的得分 + 5 +5 +5,否则若当前字符没有被 Narek 选中,则 GPT 得 1 1 1

使 S c o r e N a r e k − S c o r e G p t Score_{Narek}-Score_{Gpt} ScoreNarekScoreGpt 最大化,求这个值

思路

考虑动态规划,将二维数组优化成一维,按要求模拟计分即可,每次:
t m p [ n e x t ] = max ⁡ ( t m p [ n e x t ] , d p [ j ] + r e s ) ; tmp[next]=\max(tmp[next],dp[j]+res); tmp[next]=max(tmp[next],dp[j]+res);

C++ 代码
#include
using namespace std;
const int inf=2e9;
string t="narek";
void solve(){
	int n,m;
	cin>>n>>m;
	vector<string> s(n);
	for(int i=0;i<n;i++){
		cin>>s[i];
	}
	vector<int> dp(5,-inf),tmp;
	dp[0]=0;
	
	for(int i=0;i<n;i++){
		tmp=dp;
		for(int j=0;j<5;j++){
			if(dp[j]==-inf){
				continue;
			}
			int res=0,nxt=j;
			for(int k=0;k<m;k++){
				int p=-1;
				for(int a=0;a<5;a++){
					if(t[a]==s[i][k]){
						p=a;
						break;
					}
				}
				if(p==-1) continue;
				if(p==nxt){
					nxt=(nxt+1)%5;
					res++;
				}else{
					res--;
				}
			}
			tmp[nxt]=max(tmp[nxt],dp[j]+res);
		}
		dp=tmp;
	}
	int ans=0;
	for(int i=0;i<5;i++){
		ans=max(ans,dp[i]-2*i);
	}
	cout<<ans<<endl;
}
int32_t main(){
    int tt;
	cin>>tt;
	while(tt--){
		solve();
	}
	return 0;
}

你可能感兴趣的:(Codeforces,比赛题解,c++,算法,动态规划,数据结构,贪心算法)