Description
众所周知,yjj发现了一款新型的益智卡牌游戏叫SGK,游戏的具体内容是这样的:
(1)游戏方式:
1.游戏玩家分为两人A和B,双方生命值均为3点且各拥有不超过9张的手牌。由玩家A主动出牌发起进攻,若玩家A能打败玩家B则算玩家A胜利,否则算玩家B胜利。
2.游戏内打出的卡牌即为从手牌中丢弃。
3.为了增加游戏的乐趣,双方的手牌均为互相可见。
PS:1.玩家被打败的条件是生命值降为0,且没有恢复生命值的卡牌了。
2.若玩家已被打败,则不能够再出牌。
(2)卡牌类型:
“杀”牌(K):
1.直接打出一张指向对方,若对方不能打出一张“闪”牌进行响应,则对方损失一点生命值。(本方法只能使用一次)
2.用来响应“南蛮入侵”牌。
3.用来响应“决斗”牌。
“闪”牌(S):
1.用来响应“万箭齐发”牌。
2.用来响应“杀”牌。
“桃”牌(T):
1.在生命值降为0的时候可自动打出,为该玩家恢复一点生命值。
“南蛮入侵”牌(N):
1.直接打出一张指向对方,若对方不能打出一张“杀”牌进行响应,则对方损失一点生命值。(本方法可以使用任意次)
“万箭齐发”牌(W):
1.直接打出一张指向对方,若对方不能打出一张“闪”牌进行响应,则对方损失一点生命值。(本方法可以使用任意次)
“决斗”牌(J):
1.直接打出一张指向对方,由对方开始双方轮流打出一张“杀”牌进行响应,直到其中一方不能够打出“杀”牌为止,则该方损失一点生命值。(本方法可以使用任意次)
PS:1.用来响应的方法可以使用任意次。
2.若有牌可以响应则必须打出响应。
今天yjj邀请JS和DZ来玩这个游戏,由JS作为玩家A,DZ作为玩家B。现在告诉你JS和DZ的手牌,聪明的你能告诉yjj谁能够胜利么?
Input
首先输入一个整数T,代表有T组测试实例。(1<=T<=100)
对于每组测试,输入包含三行,第一行包含两个整数n、m,分别代表JS的手牌数和DZ的手牌数。(0<=n,m<=9)
接下两行分别代表JS的牌型和DZ的牌型,牌型均为上述牌型括号内的大写字母,用空格隔开。
Output
对于每组测试实例,若JS胜利则输出“JS”,若DZ胜利则输出“DZ”(不带引号)。
Sample Input
2
4 1
K K K K
S
4 1
W W W W
S
Sample Output
DZ
JS
思路:传统的三国杀游戏,这里题目中需要注意的几点
1.JS为玩家A,为先手
2.A的获胜条件,只有A在第一回合杀死B才算胜利
那么我们只需要考录A的出牌顺序,判断能否杀掉B即可。那么具体怎么考虑呢?仔细思考,只要尽可能多的杀掉对方的血即可。我们遵守下面的逻辑顺序
1.首先桃子是无差别的,每个人第一回合最大生命值(可能会超过三点)相当于每个人的血量加拥有的桃子数量
2.将万箭齐发放完,因为万箭齐发B只能用闪响应,且不可能对A造成伤害
3.判断此时B是否有闪,如果有闪,则不出杀,因为出杀没有意义,消耗对方一个闪不会造成伤害,我们的万箭齐发也用完,对方也不再需要用闪躲避攻击了。而且我们不出杀节省下来的杀可以留着后面决斗用!相反,如果对方没有闪,我们出杀,砍掉B一点血
4.为了给对方造成最大的杀伤,假如我们的决斗和杀够,先使用决斗,手中有杀就响应,直到A被杀成1滴血或者是对方死亡
5.这个时候A的决斗已经最大可能的消耗了B的杀,此时A将南蛮入侵全部放完杀伤最优
6.这个时候如果对方还没死,我们手中只有决斗了,那么如果将对方决斗死了且自己没死,就A胜,否则A一定就输了
理清了就很简单了,下面是我的丑代码,主要是每一步的时候将,对应的剩余牌数、血量变化清楚即可
#include<bits/stdc++.h>
using namespace std;
int k[2],s[2],n[2],w[2],t[2],j[2],life[2];
void add(char sign,int pos){
if(sign=='K') k[pos]++;
else if(sign=='S') s[pos]++;
else if(sign=='N') n[pos]++;
else if(sign=='W') w[pos]++;
else if(sign=='J') j[pos]++;
else if(sign=='T') t[pos]++;
}
int main(){
//freopen("input.txt","r",stdin);
int T,k1,k2;
string sign;
scanf("%d",&T);
while(T--){
k[0]=k[1]=s[0]=s[1]=n[0]=n[1]=0;
w[0]=w[1]=t[0]=t[1]=j[0]=j[1]=0;
life[0]=life[1]=3;
scanf("%d%d",&k1,&k2);
for(int i=1;i<=k1;i++){
cin>>sign;
add(sign[0],0);
}
for(int i=1;i<=k2;i++){
cin>>sign;
add(sign[0],1);
}
life[0]+=t[0];
life[1]+=t[1];
if(w[0]<=s[1]) { //全部放万箭齐发
s[1]-=w[0];
w[0]=0;
}
else {
life[1]-=(w[0]-s[1]);
w[0]=0;
s[1]=0;
}
if(life[1]<=0) {
cout<<"JS"<<endl;
continue;
}
if(s[1]==0&&k[0]>0){ //如果B没有闪了,杀有用 ,否则是不变的
life[1]--;
k[0]--;
}
if(life[1]<=0) {
cout<<"JS"<<endl;
continue;
}
while(life[0]>1&&j[0]>0){ //先决斗消耗杀 ,前提是保证自己没死
if(k[0]>=k[1]){
life[1]--;
k[0]-=k[1];
k[1]=0;
}
else {
k[1]-=(k[0]+1);
k[0]=0;
life[0]--;
}
j[0]--;
if(life[1]<=0) break; //把B砍死了也就结束了
}
if(life[1]<=0) {
cout<<"JS"<<endl;
continue;
}
if(n[0]>=k[1]){ //再放所有南蛮
life[1]-=(n[0]-k[1]);
n[0]=0;
k[1]=0;
}
else {
n[0]=0;
k[1]-=n[0];
}
if(life[1]<=0) {
cout<<"JS"<<endl;
continue;
}
while(life[0]>0&&life[1]>0&&j[0]>0){ //放出所有决斗,知道有人死或者决斗放完
if(k[0]>=k[1]){
life[1]--;
k[0]-=k[1];
k[1]=0;
}
else {
k[1]-=(k[0]+1);
life[0]--;
}
j[0]--;
}
if(life[1]<=0) {
cout<<"JS"<<endl;
continue;
}
cout<<"DZ"<<endl;
}
return 0;
}