zzuli_acm_oj 1851 KILL 小模拟
有点小坑的模拟题,先解释下题意:
三国杀的简化版本,牌型有杀,闪,桃,万箭齐发,南蛮入侵,决斗
玩家是JS和DZ,JS行动一个回合,如果JS可以打死DZ,那么JS胜;否则DZ胜
题中解释的是:
杀只能用一次,必须响应,那么我们可以采取如下的贪心策略:
我们的目标是尽可能让DZ去死,那么就要集中火力打掉他的闪和杀(他的万箭齐发,南蛮入侵,决斗是没有用的),他的桃子可以直接计算到血量上限上去
跟DZ的闪有关的牌:
杀(只能用一次),万箭齐发(多次)
所以,我们直接把所有的万箭齐发全部用掉,尽可能的消耗DZ的闪(没有闪就掉血)
杀这张牌呢,要用贪心的思想考虑:如果DZ没有闪了,那么我们需要用这张杀(因为马上可以让他掉血,留着这张杀可能在决斗中有用,也可能没用,所以先用掉更优)
跟DZ的杀有关的牌:
决斗(多次),南蛮(多次),杀(在决斗中使用)
玩过三国杀的朋友,应该会知道又***这个功能的吧!比如如下这个数据:
5 2
J J J J J
K K
这个数据是JS赢的,因为先手在保证自己不被对手斗死的情况下,可以一直出决斗来浪费DZ的杀,进而可以用决斗或者南蛮入侵解决!
所以,我们在保证JS不死的前提下,一直决斗
注意决斗的规则:当JS的杀的数量不小于DZ的杀的数量时,DZ掉一血,消耗的杀的数量相等;否则,JS掉一血,DZ比JS多用一张杀
因为题中描述说有杀必须响应,所以至少把其中一个玩家的杀打光为止
接着把所有的南蛮入侵放掉,继续消耗杀(因为有可能DZ还有杀,再决斗自己就死了,所以先南蛮消耗杀,留着决斗)
最后,再把所有的决斗放掉(为什么这个时候不用保证自己不被对手斗死了呢?)
因为胜负条件:只要JS没把DZ打死,那么DZ胜;所以我们可以直接使用光所有的决斗,要么把JS打死了,要么把DZ打死了,要么数量不够
所以贪心策略:
先万箭齐发,再杀(在DZ没闪的情况),保证JS不死尽可能决斗,所有的南蛮入侵,用光决斗
代码如下:
#include<bits/stdc++.h>
using namespace std;
struct People{
int K,S,N,W,J,Cnt;
}A,B;
char in[10];
int T,n,m;
void Add(People &X,char choose){
if (choose=='K') X.K++;
else if (choose=='S') X.S++;
else if (choose=='N') X.N++;
else if (choose=='W') X.W++;
else if (choose=='J') X.J++;
else if (choose=='T') X.Cnt++;
}
void Clear(People &X){
X.K = X.S = X.N = X.W = X.J = X.Cnt = 0;
}
void Print(People X){
printf("K:%d S:%d N:%d W:%d J:%d Cnt:%d\n",X.K,X.S,X.N,X.W,X.J,X.Cnt);
}
int main(){
//freopen("input.txt","r",stdin);
scanf("%d",&T);
while(T--){
Clear(A);Clear(B);
scanf("%d%d",&n,&m);
for(int i=1;i<=n;i++){
scanf("%s",in);
Add(A,in[0]);
}
for(int i=1;i<=m;i++){
scanf("%s",in);
Add(B,in[0]);
}
A.Cnt+=3;
B.Cnt+=3;
//所有的W用完
if (A.W > 0){
if (A.W >= B.S){
B.Cnt = B.Cnt - (A.W - B.S);
B.S = 0;
}
else{
B.S = B.S - A.W;
}
}
if (A.K > 0 && B.S == 0){
B.Cnt--;
A.K--;
}
//然后使用J
while (A.J > 0 && A.Cnt > 1){
if (A.K >= B.K){
A.K -= B.K;
B.K = 0;
B.Cnt--;
}
else{
B.K -= (A.K+1);
A.K = 0;
A.Cnt--;
}
A.J--;
}
if (A.N > 0){
if (A.N >= B.K){
B.Cnt = B.Cnt - (A.N - B.K);
B.K = 0;
}
else{
B.K = B.K - A.N;
}
}
while (A.J > 0 && A.Cnt > 0){
if (A.K >= B.K){
A.K -= B.K;
B.K = 0;
B.Cnt--;
}
else{
B.K -= (A.K+1);
A.K = 0;
A.Cnt--;
}
A.J--;
}
if (B.Cnt <= 0) puts("JS");
else puts("DZ");
}
return 0;
}
//zzuli_1851
附几个Hack数据:
6 3
J J J N N N
K K K
6 3
J J J J J N
K K K
6 3
J J J N K W
K K S
4 2
J N N K
K S
6 4
J K K K N N
K K K K
6 3
J K K K N N
K K K
8 3
J J K K K K N N
K K K K
5 2
J J J N K
K K