码迷,mamicode.com
首页 > 其他好文 > 详细

HDU 4930 Fighting the Landlords(模拟)

时间:2014-08-10 01:36:09      阅读:368      评论:0      收藏:0      [点我收藏+]

标签:style   blog   http   color   os   io   for   art   

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

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

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

如果一次性打不完:

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

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

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

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

bubuko.com,布布扣
  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 }        
View Code

 

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

HDU 4930 Fighting the Landlords(模拟)

标签:style   blog   http   color   os   io   for   art   

原文地址:http://www.cnblogs.com/xiaxiaosheng/p/3901804.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!