BYRBT

TYVJ P1092 麻将

题目:

http://tyvj.cn/Problem_Show.asp?id=1092

 

题解:

  不解释………………自己去看代码吧……………………

 

View Code
  1 #include<cstdio>
  2 #include<cstdlib>
  3 #include<cstring>
  4 
  5 using namespace std;
  6 
  7 int num[10][20],num2[10][20],t;
  8 
  9 char s[40];
 10 
 11 bool dfs(int now)
 12 {
 13     if (now==5)
 14     {
 15         for (int a=1;a<=3;a++)
 16             for (int b=1;b<=9;b++)
 17                 if (num[a][b]!=0)
 18                 {
 19                     if (num[a][b]!=2) return false;
 20                 }
 21         return true;
 22     }
 23     for (int a=1;a<=3;a++)
 24         for (int b=1;b<=9;b++)
 25             if (num[a][b]!=0)
 26             {
 27                 if (num[a][b+1]!=0 && num[a][b+2]!=0)
 28                 {
 29                     num[a][b]--;
 30                     num[a][b+1]--;
 31                     num[a][b+2]--;
 32                     if (dfs(now+1))
 33                     {
 34                         num[a][b]++;
 35                         num[a][b+1]++;
 36                         num[a][b+2]++;
 37                         return true;
 38                     }
 39                     num[a][b]++;
 40                     num[a][b+1]++;
 41                     num[a][b+2]++;
 42                 }
 43                 if (num[a][b]>=3)
 44                 {
 45                     num[a][b]-=3;
 46                     if (dfs(now+1))
 47                     {
 48                         num[a][b]+=3;
 49                         return true;
 50                     }
 51                     num[a][b]+=3;
 52                 }
 53             }
 54     return false;
 55 }
 56 
 57 bool check()//检查是否能和
 58 {
 59     return dfs(1);
 60 }
 61 
 62 int work1()//平和(一番):4个顺子组成
 63 {
 64     for (int a=1;a<=3;a++)
 65         for (int b=1;b<=9;b++)
 66             if (num[a][b]>=2)
 67             {
 68                 for (int c=1;c<=3;c++)
 69                     for (int d=1;d<=9;d++)
 70                         num2[c][d]=num[c][d];
 71                 num2[a][b]-=2;
 72                 bool able=true;
 73                 for (int c=1;c<=3;c++)
 74                 {
 75                     if (!able) break;
 76                     for (int d=1;d<=9;d++)
 77                         if (num2[c][d]!=0)
 78                         {
 79                             if (num2[c][d+1]==0 || num2[c][d+2]==0)
 80                             {
 81                                 able=false;
 82                                 break;
 83                             }
 84                             num2[c][d]--;
 85                             num2[c][d+1]--;
 86                             num2[c][d+2]--;
 87                             d--;
 88                         }
 89                 }
 90                 if (able) return 1;
 91             }
 92     return 0;
 93 }
 94 
 95 int work2()//断幺九(一番):胡牌的时候手上只有2-8的数字组成的牌型
 96 {
 97     if (num[1][1] || num[2][1] || num[3][1] || num[1][9] || num[2][9] || num[3][9]) return 0;
 98     else return 1;
 99 }
100 
101 int work3()//一杯口(一番):同花色同数值的顺子两组
102 {
103     for (int a=1;a<=3;a++)
104         for (int b=1;b<=9;b++)
105             if (num[a][b]>=2)
106             {
107                 for (int c=1;c<=3;c++)
108                     for (int d=1;d<=9;d++)
109                         num2[c][d]=num[c][d];
110                 num2[a][b]-=2;
111                 bool able=true;
112                 for (int c=1;c<=3;c++)
113                 {
114                     if (!able) break;
115                     for (int d=1;d<=9;d++)
116                         if (num2[c][d]!=0)
117                         {
118                             if (num2[c][d]>=2 && num2[c][d+1]>=2 && num2[c][d+2]>=2) return 1;
119                             if (num2[c][d+1]==0 || num2[c][d+2]==0)
120                             {
121                                 able=false;
122                                 break;
123                             }
124                             num2[c][d]--;
125                             num2[c][d+1]--;
126                             num2[c][d+2]--;
127                             d--;
128                         }
129                 }
130             }
131     return 0;
132 }
133 
134 bool dfs2(int now)
135 {
136     if (now==5) return true;
137     for (int a=1;a<=3;a++)
138         for (int b=1;b<=9;b++)
139             if (num2[a][b]!=0)
140             {
141                 if (num2[a][b+1]!=0 && num2[a][b+2]!=0 && (b==1 || b+2==9))
142                 {
143                     num2[a][b]--;
144                     num2[a][b+1]--;
145                     num2[a][b+2]--;
146                     if (dfs2(now+1)) return true;
147                     num2[a][b]++;
148                     num2[a][b+1]++;
149                     num2[a][b+2]++;
150                 }
151                 if (num2[a][b]>=3 && (b==1 || b==9))
152                 {
153                     num2[a][b]-=3;
154                     if (dfs2(now+1)) return true;
155                     num2[a][b]+=3;
156                 }
157             }
158     return false;
159 }
160 
161 int work4()//混全带幺九(一番):全部的顺子,刻子中都含有数字1或9
162 {
163     for (int a=1;a<=3;a++)
164         for (int b=1;b<=9;b++)
165             if (num[a][b]>=2)
166             {
167                 for (int c=1;c<=3;c++)
168                     for (int d=1;d<=9;d++)
169                         num2[c][d]=num[c][d];
170                 num2[a][b]-=2;
171                 if (dfs2(1)) return 1;
172             }
173     return 0;
174 }
175 
176 int work5()//三色同顺(一番):三种花色同数值的顺子各一组
177 {
178     for (int a=1;a<=3;a++)
179         for (int b=1;b<=9;b++)
180             if (num[a][b]>=2)
181             {
182                 for (int c=1;c<=3;c++)
183                     for (int d=1;d<=9;d++)
184                         num2[c][d]=num[c][d];
185                 num2[a][b]-=2;
186                 for (int c=1;c<=9;c++)
187                     if (num2[1][c] && num2[2][c] && num2[3][c] && num2[1][c+1] && num2[2][c+1] && num2[3][c+1] && num2[1][c+2] && num2[2][c+2] && num2[3][c+2])
188                     {
189                         num2[1][c]--;num2[1][c+1]--;num2[1][c+2]--;
190                         num2[2][c]--;num2[2][c+1]--;num2[2][c+2]--;
191                         num2[3][c]--;num2[3][c+1]--;num2[3][c+2]--;
192                         bool able,find=false;
193                         for (int c=1;c<=3;c++)
194                         {
195                             if (find) break;
196                             for (int d=1;d<=9;d++)
197                                 if (num2[c][d]!=0)
198                                 {
199                                     find=true;
200                                     if (num2[c][d]==3) able=true;
201                                     else
202                                     {
203                                         if (num2[c][d]==1 && num2[c][d+1]==1 && num2[c][d+2]==1) able=true;
204                                         else able=false;
205                                     }
206                                     break;
207                                 }
208                         }
209                         if (able) return 1;
210                     }
211             }
212     return 0;
213 }
214 
215 int work6()//一气贯通(一番):由同花色一至九组成顺子
216 {
217     for (int a=1;a<=3;a++)
218         for (int b=1;b<=9;b++)
219             if (num[a][b]>=2)
220             {
221                 for (int c=1;c<=3;c++)
222                     for (int d=1;d<=9;d++)
223                         num2[c][d]=num[c][d];
224                 num2[a][b]-=2;
225                 for (int c=1;c<=3;c++)
226                     if (num2[c][1] && num2[c][2] && num2[c][3] && num2[c][4] && num2[c][5] && num2[c][6] && num2[c][7] && num2[c][8] && num2[c][9])
227                     {
228                         num2[c][1]--;
229                         num2[c][2]--;
230                         num2[c][3]--;
231                         num2[c][4]--;
232                         num2[c][5]--;
233                         num2[c][6]--;
234                         num2[c][7]--;
235                         num2[c][8]--;
236                         num2[c][9]--;
237                         bool able=false,find=false;
238                         for (int d=1;d<=3;d++)
239                         {
240                             if (find) break;
241                             for (int e=1;e<=9;e++)
242                                 if (num2[d][e]!=0)
243                                 {
244                                     find=true;
245                                     if (num2[d][e]==3) able=true;
246                                     else
247                                     {
248                                         if (num2[d][e+1]==1 && num2[d][e+2]==1) able=true;
249                                         else able=false;
250                                     }
251                                     break;
252                                 }
253                         }
254                         if (able) return 1;
255                     }
256             }
257     return 0;
258 }
259 
260 int work7()//一色三顺(两番):同花色同数值顺子三组
261 {
262     for (int a=1;a<=3;a++)
263         for (int b=1;b<=9;b++)
264             if (num[a][b]>=2)
265             {
266                 for (int c=1;c<=3;c++)
267                     for (int d=1;d<=9;d++)
268                         num2[c][d]=num[c][d];
269                 num2[a][b]-=2;
270                 for (int c=1;c<=3;c++)
271                     for (int d=1;d<=9;d++)
272                         if (num2[c][d]>=3 && num2[c][d+1]>=3 && num2[c][d+2]>=3)
273                         {
274                             num2[c][d]-=3;
275                             num2[c][d+1]-=3;
276                             num2[c][d+2]-=3;
277                             bool able=false,find=false;
278                             for (int d=1;d<=3;d++)
279                             {
280                                 if (find) break;
281                                 for (int e=1;e<=9;e++)
282                                     if (num2[d][e]!=0)
283                                     {
284                                         find=true;
285                                         if (num2[d][e]==3) able=true;
286                                         else
287                                         {
288                                             if (num2[d][e+1]==1 && num2[d][e+2]==1) able=true;
289                                             else able=false;
290                                         }
291                                         break;
292                                     }
293                             }
294                             if (able) return 2;
295                         }
296             }
297     return 0;
298 }
299 
300 int work8()//对对和(两番):四组刻子
301 {
302     for (int a=1;a<=3;a++)
303         for (int b=1;b<=9;b++)
304             if (num[a][b]>=2)
305             {
306                 for (int c=1;c<=3;c++)
307                     for (int d=1;d<=9;d++)
308                         num2[c][d]=num[c][d];
309                 num2[a][b]-=2;
310                 bool able=true;
311                 for (int c=1;c<=3;c++)
312                     for (int d=1;d<=9;d++)
313                         if (num2[c][d]!=0)
314                         {
315                             if (num2[c][d]!=3) able=false;
316                         }
317                 if (able) return 2;
318             }
319     return 0;
320 }
321 
322 int work9()//两杯口(三番):由两组不同的一杯口组成
323 {
324     for (int a=1;a<=3;a++)
325         for (int b=1;b<=9;b++)
326             if (num[a][b]>=2)
327             {
328                 for (int c=1;c<=3;c++)
329                     for (int d=1;d<=9;d++)
330                         num2[c][d]=num[c][d];
331                 num2[a][b]-=2;
332                 bool able=true,find=false;
333                 for (int c=1;c<=3;c++)
334                 {
335                     if (find) break;
336                     for (int d=1;d<=9;d++)
337                         if (num2[c][d]!=0)
338                         {
339                             find=true;
340                             if (num2[c][d]<2 || num2[c][d+1]<2 || num2[c][d+2]<2)
341                             {
342                                 able=false;
343                                 break;
344                             }
345                             else
346                             {
347                                 num2[c][d]-=2;
348                                 num2[c][d+1]-=2;
349                                 num2[c][d+2]-=2;
350                                 bool find=false;
351                                 for (int e=1;e<=3;e++)
352                                 {
353                                     if (find) break;
354                                     for (int f=1;f<=9;f++)
355                                         if (num2[e][f]!=0)
356                                         {
357                                             find=true;
358                                             if (e==c && f==d)
359                                             {
360                                                 able=false;
361                                                 break;
362                                             }
363                                             if (num2[e][f]!=2 || num2[e][f+1]!=2 || num2[e][f+2]!=2) able=false;
364                                             break;
365                                         }
366                                 }
367                                 break;
368                             }
369                         }
370                 }
371                 if (able) return 3;
372             }
373     return 0;
374 }
375 
376 int work10()//三色同刻(三番):三种花色同数值的刻子各一组
377 {
378     for (int a=1;a<=3;a++)
379         for (int b=1;b<=9;b++)
380             if (num[a][b]>=2)
381             {
382                 for (int c=1;c<=3;c++)
383                     for (int d=1;d<=9;d++)
384                         num2[c][d]=num[c][d];
385                 num2[a][b]-=2;
386                 for (int c=1;c<=9;c++)
387                     if (num2[1][c]>=3 && num2[2][c]>=3 && num2[3][c]>=3)
388                     {
389                         num2[1][c]-=3;
390                         num2[2][c]-=3;
391                         num2[3][c]-=3;
392                         bool able=false,find=false;
393                         for (int d=1;d<=3;d++)
394                         {
395                             if (find) break;
396                             for (int e=1;e<=9;e++)
397                                 if (num2[d][e]!=0)
398                                 {
399                                     find=true;
400                                     if (num2[d][e]==3) able=true;
401                                     else
402                                     {
403                                         if (num2[d][e+1]==1 && num2[d][e+2]==1) able=true;
404                                         else able=false;
405                                     }
406                                     break;
407                                 }
408                         }
409                         if (able) return 3;
410                     }
411             }
412     return 0;
413 }
414 
415 int work11()//清一色(六番):全部由同一种花色的顺子,刻子及雀头组成
416 {
417     for (int a=1;a<=3;a++)
418     {
419         int nowsum=0;
420         for (int b=1;b<=9;b++)
421             nowsum+=num[a][b];
422         if (nowsum==14) return 6;
423     }
424     return 0;
425 }
426 
427 int work12()//清老头(六番):全部由1或9的刻子和雀头组成
428 {
429     for (int a=1;a<=3;a++)
430         for (int b=2;b<=8;b++)
431             if (num[a][b]) return 0;
432     return 6;
433 }
434 
435 int main()
436 {
437     scanf("%d",&t);
438     for (int a=1;a<=t;a++)
439     {
440         scanf("%s",s+1);
441         memset(num,0,sizeof(num));
442         for (int a=1;a<=14;a++)
443         {
444             switch(s[a*2])
445             {
446                 case 'w':
447                     {
448                         num[1][s[a*2-1]-'0']++;
449                         break;
450                     }
451                 case 's':
452                     {
453                         num[2][s[a*2-1]-'0']++;
454                         break;
455                     }
456                 case 't':
457                     {
458                         num[3][s[a*2-1]-'0']++;
459                         break;
460                     }
461             }
462         }
463         if (!check())//检查是否能和
464         {
465             printf("0\n");
466             continue;
467         }
468         int ans=0;
469         ans+=work1();//平和(一番):4个顺子组成
470         ans+=work2();//断幺九(一番):胡牌的时候手上只有2-8的数字组成的牌型
471         ans+=work3();//一杯口(一番):同花色同数值的顺子两组
472         ans+=work4();//混全带幺九(一番):全部的顺子,刻子中都含有数字1或9
473         ans+=work5();//三色同顺(一番):三种花色同数值的顺子各一组
474         ans+=work6();//一气贯通(一番):由同花色一至九组成顺子
475         ans+=work7();//一色三顺(两番):同花色同数值顺子三组
476         ans+=work8();//对对和(两番):四组刻子
477         ans+=work9();//两杯口(三番):由两组不同的一杯口组成
478         ans+=work10();//三色同刻(三番):三种花色同数值的刻子各一组
479         ans+=work11();//清一色(六番):全部由同一种花色的顺子,刻子及雀头组成
480         ans+=work12();//清老头(六番):全部由1或9的刻子和雀头组成
481         printf("%d\n",ans);
482     }
483     return 0;
484 }
posted @ 2012-07-10 09:38  zhonghaoxi  阅读(466)  评论(0编辑  收藏  举报
BYRBT