HDU 4930 Fighting the Landlords(模拟)

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=4930

解题报告:斗地主,加了一个四张可以带两张不一样的牌,也可以带一对,判断打出一手牌之后,如果对手没有能够大过你的牌就输出Yes,或者如果你把手上的牌一次性打完也输出Yes,否则输出No,代码有280多行,表示光是敲代码就花了一个多小时,手速还是太慢。

1、首先判断手上的牌能不能一次打完

如果一次性打不完:

2、首先判断对方有没有一对王,有就输出No

3、判断对手有没有四张的牌,如果有,再判断自己有没有四张的牌,如果对手有自己没有就是输,如果自己有对手没有自己有就是赢,如果两个人都有就看谁的更大,如果两个人都没有,则继续判断

4、最后一步,尝试将自己的牌组合成前面的六种打法打出去,然后判断对手有没有可以大过自己的牌,如果有就继续判断,如果没有就是赢。

详细情况看代码吧,有详细的注释。

  1 #include<cstdio>
  2 #include<cstring>
  3 #include<iostream>
  4 #include<algorithm>
  5 #include<deque>
  6 using namespace std;
  7
  8 void exchto(char* str,int* num)   //先把输入预处理成各种牌的张数num[i]表示第i大的牌有多少张
  9 {
 10     int len = strlen(str);
 11     for(int i = 0;i < len;++i)
 12     {
 13         if(str[i] >= ‘3‘ && str[i] <= ‘9‘)
 14         num[str[i]-‘0‘-2]++;
 15         if(str[i] == ‘T‘) num[8]++;
 16         if(str[i] == ‘J‘) num[9]++;
 17         if(str[i] == ‘Q‘) num[10]++;
 18         if(str[i] == ‘K‘) num[11]++;
 19         if(str[i] == ‘A‘) num[12]++;
 20         if(str[i] == ‘2‘) num[13]++;
 21         if(str[i] == ‘X‘) num[14]++;
 22         if(str[i] == ‘Y‘) num[15]++;
 23     }
 24 }
 25 int judge_once(const int* num)    //判断能否一次打完或者自己有Nuke的情况
 26 {
 27     if(num[14] && num[15])    //Nuke
 28     return 1;
 29     int n = 0;
 30     for(int i = 1;i <= 15;++i)
 31     if(num[i] != 0) n++;
 32     if(n > 3) return 0;   //牌种类数大于3不可能一次打完
 33     if(n == 1) return 1;  //等于1一定可以一次打完
 34     if(n == 2)
 35     {
 36         for(int i = 1;i <= 13;++i)
 37         for(int j = 1;j < i;++j)
 38         {
 39             if(num[i] == 3 && num[j] >= 1 && num[j] <= 2)
 40             return 1;
 41             if(num[j] == 3 && num[i] >= 1 && num[i] <= 2)
 42             return 1;
 43             if(num[i] == 4 &&  num[j] == 2)
 44             return 1;
 45             if(num[j] == 4 && num[i] == 2)
 46             return 1;
 47         }
 48     }
 49     else if(n == 3)
 50     {
 51         int flag = -1;
 52         for(int i = 1;i <= 13;++i)
 53         if(num[i] == 4 && flag == -1) flag = 1;
 54         else if(num[i] == 4 && flag == 1) flag = 0;
 55         if(flag <= 0) return 0;   //没有4或者有多个4张的,不行
 56         int m = 0;
 57         for(int i = 1;i <= 13;++i)
 58         if(num[i] == 1) m++;
 59         if(m == 2) return 1;
 60         return 0;
 61     }
 62     return 0;
 63 }
 64 int judge_have4(const int* num1,const int* num2)    //判断双方是否存在4
 65 {
 66     int a = 16,b = 16;
 67     for(int i = 13;i >= 1;--i)
 68     if(num1[i] == 4)
 69     {
 70         a = i;
 71         break;
 72     }
 73     for(int i = 13;i >= 1;--i)
 74     if(num2[i] == 4)
 75     {
 76         b = i;
 77         break;
 78     }
 79     if(b != 16 && a == 16) return -1;  //对手有4而自己没有4张的情况
 80     if(a != 16 && b == 16) return 1;  //自己有4而对手没四
 81     if(a == 16 && b == 16) return 0;
 82     if(a >= b) return 1;
 83     else if(a < b) return -1;
 84 }
 85 /////////下面尝试前六种不同的打法,如果可以用该打法赢,返回1,否则返回0
 86 int  judge1(const int* num1,const int* num2)
 87 {
 88     int a = 16,b = 16;
 89     for(int i = 15;i >= 1;--i)
 90     if(num1[i] != 0)
 91     {
 92         a = i;
 93         break;
 94     }
 95     for(int i = 15;i >= 1;--i)
 96     if(num2[i] != 0)
 97     {
 98         b = i;
 99         break;
100     }
101     return a >= b;   //因为双方至少有一张牌,否则要判断是否有没找到的情况
102 }
103 int judge2(const int* num1,const int* num2)
104 {
105     int a = 16,b = 16;
106     for(int i = 15;i >= 1;--i)
107     if(num1[i] >= 2)
108     {
109         a = i;
110         break;
111     }
112     for(int i = 15;i >= 1;--i)
113     if(num2[i] >= 2)
114     {
115         b = i;
116         break;
117     }
118     if(a != 16 && b == 16) return 1;
119     if(a == 16 && b == 16) return 0;
120     if(a != 16 && b != 16) return a >= b;
121     return 0;
122 }
123 int judge3(const int* num1,const int* num2)
124 {
125      int a = 16,b = 16;
126      for(int i = 15;i >= 1;--i)
127      if(num1[i] >= 3)
128      {
129          a = i;
130          break;
131      }
132      for(int i = 15;i >= 1;--i)
133      if(num2[i] >= 3)
134      {
135          b = i;
136          break;
137      }
138      if(a != 16 && b == 16) return 1;
139      if(a == 16 && b == 16) return 0;
140      if(a != 16 && b != 16) return a >= b;
141      return 0;
142 }
143 int judge4(const int* num1,const int* num2)
144 {
145     int a = 16,b = 16,c = 0,d = 0;
146     for(int i = 15;i >= 1;--i)
147     if(num1[i] >= 3)
148     {
149         a = i;
150         break;
151     }
152     for(int i = 15;i >= 1;--i)
153     if(num2[i] >= 3)
154     {
155         b = i;
156         break;
157     }
158     if(a != 16)
159     for(int i = 1;i <= 15;++i)
160     if(i != a && num1[i] != 0)
161     {
162         c = 1;
163         break;
164     }
165     if(b != 16)
166     for(int i = 1;i <= 15;++i)
167     if(i != b && num2[i] != 0)
168     {
169         d = 1;
170         break;
171     }
172     if(a != 16 && c == 1 && (b == 16 || d == 0)) return 1;  //当对手有三个但没有1个另外的也不满足这种打法
173     if(a == 16 && b == 16) return 0;
174     if(a != 16 && b != 16 && c == 1 && d == 1) return a >= b;
175     return 0;
176 }
177 int judge5(const int* num1,const int* num2)
178 {
179     int a = 16,b = 16,c = 0,d = 0;
180     for(int i = 15;i >= 1;--i)
181     if(num1[i] >= 3)
182     {
183         a = i;
184         break;
185     }
186     for(int i = 15;i >= 1;--i)
187     if(num2[i] >= 3)
188     {
189         b = i;
190         break;
191     }
192     if(a != 16)
193     for(int i = 1;i <= 15;++i)
194     if(i != a && num1[i] >= 2)
195     {
196         c = 1;
197         break;
198     }
199     if(b != 16)
200     for(int i = 1;i <= 15;++i)
201     if(i != b && num2[i] >= 2)
202     {
203         d = 1;
204         break;
205     }
206     if(a != 16 && c == 1 && (b == 16 || d == 0)) return 1;  //当对手有三个但没有1个另外的也不满足这种打法
207     if(a == 16 && b == 16) return 0;
208     if(a != 16 && b != 16 && c == 1 && d == 1) return a >= b;
209     return 0;
210 }
211 int judge6(const int* num1,const int* num2)
212 {
213     int a = 16,b = 16,c = 0,d = 0;
214     for(int i = 15;i >= 1;--i)
215     if(num1[i] >= 4)
216     {
217         a = i;
218         break;
219     }
220     for(int i  = 15;i >= 1;--i)
221     if(num2[i] >= 4)
222     {
223         b = i;
224         break;
225     }
226     if(a != 16)
227     for(int i = 1;i <= 15;++i)
228     if(i != a && num1[i] >= 1)
229     c++;
230     if(b != 16)
231     for(int i = 1;i <= 15;++i)
232     if(i != b && num2[i] >= 1)
233     d++;
234     if(a != 16 && c >= 2 && b == 16) return 1;
235     if(a == 16 && b == 16) return 0;
236     if(a != 16 && b != 16 && c >= 2 && d >= 2) return a >= b;
237     return 0;
238 }
239
240 int main()
241 {
242 //    freopen("1003.txt","r",stdin);
243 //    freopen("out1.txt","w",stdout);
244     int T;
245
246     char one[20],two[20];
247     int num1[20],num2[20];
248     scanf("%d",&T);
249     while(T--)
250     {
251         scanf("%s%s",one,two);
252         memset(num1,0,sizeof(num1));
253         memset(num2,0,sizeof(num2));
254         exchto(one,num1);
255         exchto(two,num2);
256         if(judge_once(num1))    //判断能否一次打完
257         {
258             puts("Yes");
259             continue;
260         }
261         if(num2[14] && num2[15]) //对手有Nuke直接输
262         {
263             puts("No");
264             continue;
265         }
266         int tt1 = judge_have4(num1,num2);  //判断双方是否存在4
267         ///////直接赢返回1,直接输返回-1,还有希望返回0
268         if(tt1 == 1 || tt1 == -1)    //可以判断出结果
269         {
270             printf(tt1 == 1? "Yes\n":"No\n");
271             continue;
272         }
273         /////////下面尝试前六种不同的打法,如果可以用该打法赢,返回1,否则返回0
274         int flag = 0;
275         flag = max(flag,judge1(num1,num2));
276         flag = max(flag,judge2(num1,num2));
277         flag = max(flag,judge3(num1,num2));
278         flag = max(flag,judge4(num1,num2));
279         flag = max(flag,judge5(num1,num2));
280         flag = max(flag,judge6(num1,num2));
281         printf(flag? "Yes\n":"No\n");
282     }
283     return 0;
284 }        

HDU 4930 Fighting the Landlords(模拟),布布扣,bubuko.com

时间: 2024-10-05 17:12:08

HDU 4930 Fighting the Landlords(模拟)的相关文章

HDU 4930 Fighting the Landlords 模拟

_(:зゝ∠)_ 4带2居然不是炸弹,, #include <algorithm> #include <cctype> #include <cassert> #include <cstdio> #include <cstring> #include <climits> #include <vector> #include<iostream> using namespace std; #define N 18 #

hdu 4930 Fighting the Landlords (模拟)

Fighting the Landlords Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 262144/262144 K (Java/Others) Total Submission(s): 160    Accepted Submission(s): 52 Problem Description Fighting the Landlords is a card game which has been a heat for ye

HDU 4930 Fighting the Landlords(扯淡模拟题)

Fighting the Landlords 大意: 斗地主....   分别给出两把手牌,肯定都合法.每张牌大小顺序是Y (i.e. colored Joker) > X (i.e. Black & White Joker) > 2 > A (Ace) > K (King) > Q (Queen) > J (Jack) > T (10) > 9 > 8 > 7 > 6 > 5 > 4 > 3. 给你8种组合:1.

HDU 4930 Fighting the Landlords(暴力枚举+模拟)

HDU 4930 Fighting the Landlords 题目链接 题意:就是题中那几种牌型,如果先手能一步走完,或者一步让后手无法管上,就赢 思路:先枚举出两个人所有可能的牌型的最大值,然后再去判断即可 代码: #include <cstdio> #include <cstring> #include <algorithm> using namespace std; struct Player { int rank[15]; } p1, p2; int t, h

HDU 4930 Fighting the Landlords --多Trick,较复杂模拟

题意:两个人A和B在打牌,只有题目给出的几种牌能出若A第一次出牌B压不住或者A一次就把牌出完了,那么A赢,输出Yes,否则若A牌没出完而且被B压住了,那么A输,输出No. 解法:知道规则,看清题目,搞清有哪些Trick,就可以直接模拟搞了.详见代码: #include <iostream> #include <cstdio> #include <cstring> #include <cstdlib> #include <cmath> #inclu

2014多校第六场 1010 || HDU 4930 Fighting the Landlords (模拟)

题目链接 题意 : 玩斗地主,出一把,只要你这一把对方要不了或者你出这一把之后手里没牌了就算你赢. 思路 : 一开始看了第一段以为要出很多次,实际上只问了第一次你能不能赢或者能不能把牌出尽. 1 #include <cstdio> 2 #include <cstring> 3 #include <iostream> 4 5 using namespace std ; 6 7 char str1[20],str2[20] ; 8 int hash1[20],hash2[2

hdu 4930 Fighting the Landlords

Fighting the Landlords Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 262144/262144 K (Java/Others) Total Submission(s): 480    Accepted Submission(s): 163 Problem Description Fighting the Landlords is a card game which has been a heat for y

HDU 4930 Fighting the Landlords (超级暴力+读懂题意)

题目链接:HDU 4930 Fighting the Landlords 斗地主!!.不会玩这游戏,真是苦逼.题意其他都还好,就是要注意只要第一个回合1号玩家能压制2号玩家就算赢了(突破点). 其他就分类暴力了,思路还是比较清晰的. 注意点: 1.对方炸弹,必输 2.一回合就出完牌,必胜 AC代码: #include<stdio.h> #include<string.h> int vis1[30],vis2[30]; int find(char s) { if(s=='T') re

HDU4930 Fighting the Landlords 模拟

Fighting the Landlords Fighting the Landlords Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 262144/262144 K (Java/Others)Total Submission(s): 175    Accepted Submission(s): 61 Problem Description Fighting the Landlords is a card game which