atcoder ABC149

A 利用string支持的加法将两个字符串加起来即可。
B 如果c<=a a=a-c;
如果c>a a=0,b=max(0,b-(c-a));
C 用埃筛或者欧筛找到范围内的素数,找到大于等于所给数的最小素数即可。
D 原题传送门
贪心即可,贪心策略:由于前后两次间隔k的回合不能出一样的,因此对于连续m次同样的出手,最多只能获胜(m+1)/2次。以k为间隔遍历所有回合统计三种各自能获胜的回合数即可。

AC代码:

#include 
#include 
#include 
using namespace std;
map<char,int> ans;	//分别储存赢石头(r),剪刀(s),布(p)的回合数。
int main(){
	int n,k;
	int a1,a2,a3;
	cin>>n>>k;
	cin>>a1>>a2>>a3;	//分别储存石头,剪刀,布获胜对应权值。
	string s;
	cin>>s;
	for(int i=0;i<k;i++){		//以k为间隔遍历所有回合
		int left=i,cnt=0;		//left储存出手相同的回合的左边界,cnt储存当前出手相同的回合数
		for(int j=i;j<s.size();j=j+k){
			if(s[j]==s[left])	cnt++;		//相同,则cnt加1,继续
			else{
				ans[s[left]]+=(cnt+1)/2;
				cnt=1;
				left=j;	//否则刷新左边界与cnt,储存当前的值。
			}
		}		
		ans[s[left]]+=(cnt+1)/2;	
	}
	int Ans=ans['r']*a3+ans['s']*a1+ans['p']*a2;	//此处一定要对应正确,例如r是用P获胜的,因此是ans['r']*a3;
	cout<<Ans<<endl;
	return 0;
}

E

你可能感兴趣的:(牛客)