2020 CCPC Wannafly Winter Camp Day6——C—酒馆战棋——模拟贪心

链接:https://ac.nowcoder.com/acm/contest/4137/C
来源:牛客网

时间限制:C/C++ 1秒,其他语言2秒
空间限制:C/C++ 262144K,其他语言524288K
64bit IO Format: %lld
题目描述
酒馆战棋是一个很有趣的游戏,这个游戏一共有两名玩家,每个玩家各自控制一定数量的随从,随从从左往右排列。
随从有两个基础属性:攻击力的血量,两个随从交战后会受到对方攻击力的伤害(失去对应的血量),当一个随从的血量降到 {0}0 或者以下时会死亡。
整个对战流程如下:你的随从从左往右依次进行攻击,每次攻击是随机选择一个可以攻击的对方随从进行攻击。而对方的随从全程不动。
由于对方开了外挂,所以他的随从的血量和攻击力都是无穷大,而你的随从的攻击力和血量都是 {1}1,但是随从除了攻击力和血量以外可能还有一些其他的属性:
圣盾:圣盾可以抵挡一次伤害,抵挡伤害后圣盾会消失。
剧毒:拥有剧毒属性的随从攻击力视为无穷大(由于你的随从的攻击力都是 {1}1,所以只有剧毒属性才能击杀对方的随从)。
嘲讽:当对方场上有带有嘲讽的随从时,你只能攻击有嘲讽的随从。
现在已知你的随从从左往右分别有哪些属性,以及对方各种属性的随从有几个(显然对方随从的顺序并不会影响战斗)。
因为每次攻击是随机选择的,所以出题人经常被系统给演了,所以他想知道在所有情况下最多能消灭几只随从,以及最少能消灭几只随从。
输入描述:
第一行一个正整数 {T}T 表示数据组数 (1\leq T\leq 100)(1≤T≤100)
对于每组数据:
第一行五个整数{n,a,b,c,d}n,a,b,c,d,表示你的随从个数,以及对方的普通随从,圣盾随从,嘲讽随从,圣盾嘲讽随从的个数。(因为对方的随从的属性都是无限大,所以剧毒对他来说没有意义)
第二行一个长度为 {n}n 的 {01}01 串,第 {i}i 个字符为 {1}1 表示从左往右第 {i}i 个随从是否具有剧毒属性,若有则为 {1}1,否则为 {0}0。(因为只需要关心消灭了几个随从,所以嘲讽和圣盾属性无意义)。
保证 1\leq n\leq 10001≤n≤1000,0\leq a,b,c,d\leq 10000≤a,b,c,d≤1000
输出描述:
对于每组数据输出一行两个整数,表示最多消灭几个随从以及最少消灭几个随从。
示例1
输入
复制
1
5 2 2 2 1
10101
输出
复制
3 2

题意

很长的题意,模拟就完事了(无论是什么情况都要先攻击具有嘲讽属性的随从)
最好的情况:
如果是1:攻击的顺序为:只带有嘲讽的——>带有护盾的嘲讽(如果有的嘲讽随从护盾消失那么先攻击这一类,其次去消耗带有嘲讽的护盾)——>普通的——>带有护盾的(如果有的随从护盾消失了)
如果是0:攻击的顺序为:带有护盾的嘲讽——>(没有嘲讽的情况下)带有护盾的随从;
最坏的情况下(大概和上面相反)
如果是1:攻击的顺序为:带有护盾的嘲讽——>只带有嘲讽的——>带有护盾的随从——>普通的
如果是0:攻击的顺序为:只带有嘲讽的——>带有护盾的嘲讽(注意先攻击护盾消耗过的)——>带有护盾的——>普通的

AC代码:

#include  
using namespace std;

typedef long long ll;
const int N=1e5+7;
struct node
{
     
	int a,b;//a:代表此时还有多少随从,b:代表这一类的随从还有多少护盾
}x,y;//x代表着带有护盾的普通随从;y代表着带有护盾的嘲讽随从
int main()
{
     
	int t;
	cin >>t;
	while(t--)
	{
     
		int n,a,b,c,d;
		int z;
		cin >>z;
		int h,j,k,l;
		cin >>h>>j>>k>>l;
		string s;
		cin >>s;
		//最好的情况 
		a=h,b=k,x.a=j,x.b=j,y.a=l,y.b=l;
		int sum=0;
		for(int i=0;i<s.size();i++)
		{
     
			char st=s[i];
			if(st=='1')
			{
     
				if(b!=0) sum++,b--;
				else if(y.a!=0||y.b!=0)
				{
     
					if(y.a<=y.b) y.b--;
					else y.a--,sum++;
				}
				else if(a!=0) a--,sum++;
				else
				{
     
					if(x.a!=0||x.b!=0)
					{
     
						if(x.a<=x.b) x.b--;
						else x.a--,sum++;
					}
				}
			}
			else
			{
     
				if(y.b!=0) y.b--;
				else if(y.a!=0) continue;
				else if(b!=0) continue;
				else if(x.b!=0) x.b--;
			}
		}
		cout <<sum<<" ";
		//最坏的情况
		a=h,b=k,x.a=j,x.b=j,y.a=l,y.b=l;
		sum=0;
		for(int i=0;i<s.size();i++)
		{
     
			char st=s[i];
			if(st=='1')
			{
     
				if(y.b!=0) y.b--;
				else if(y.b==0&&y.a!=0) y.a--,sum++;
				else if(b!=0) b--,sum++;
				else if(x.b!=0) x.b--;
				else if(x.b==0&&x.a!=0) x.a--,sum++;
				else if(a!=0) a--,sum++;
			}
			else
			{
     
				if(b!=0) continue;
				else if(y.a>y.b) continue;
				else if(y.b!=0) y.b--;
				else if(a!=0) continue;
				else if(x.b!=0) x.b--;
			}
		}
		cout <<sum<<endl;
	}
}

你可能感兴趣的:(基础算法——贪心)