Fork me on GitHub

Uva 131 - The Psychic Poker Player

 The Psychic Poker Player

题目链接:

http://uva.onlinejudge.org/index.php?option=com_onlinejudge&Itemid=8&page=show_problem&problem=67

题目输入的每一行就是一个Case,前面五个表示你现在手上的牌,后面五个是放在桌上的牌,这五张牌叠在一起,牌面的值向下铺着,所以你看不到值,题目要你做的就是:你可以将你手中不要的牌拿走,可以是1张,2张...5张,当然你也可以不拿走。你从你手中的牌拿走多少张然后就从桌上的那些牌上从上到下取的方式拿走多少张,在这个的过程中,你要判断出你手中最好的牌的情况是什么,最终要把这种情况输出,这些情况在Sample中已经将所有的可能表示出来了,而且是有优先顺序的(即从上到下,上面的符合了下面的就不用判断了) 这些情况翻译成中文来就是:

//0 straight-flush   同花顺 == 一手同花的五张牌 + 五张牌点数连续的顺子
//1 four-of-a-kind    四张相同 的牌
//2 full-house        满堂红 三张同点牌加上一对
//3 flush        一手同花的五张牌
//4 straight       五张牌点数连续的顺子
//5 three-of-a-kind    三张相同的牌
//6 two-pairs     两对对子
//7 one-pair          一对对子
//8 highest-card       这个我也不知道,上面的所有情况不符合,那么就只有输出它了

为了找到最好的那种情况,你就必须从桌上分别拿:0, 1, 2, 3 ,4, 5张牌然后判断情况, 而拿了桌上的牌后(如果不为零)你就必须舍掉你手上现有的牌来替换它,然后来判断情况,比如说:你从桌上那1张牌,那么替换你手中的牌就有5种情况;你从桌上拿2张牌,你就要替换你手中的任意两张牌(C5取2中可能),等等

我的做法是:

Uva的上面的一题让我学到了位运算(如果不懂位运算,先看看我上一篇随笔),先不看桌上的牌,先想想替换你手中的牌的情况共有多少种?核心是这段代码:

for(int i=0; i<(1<<5); ++i)
{
  int num = 0;
  for(int j=0; j<5; ++j)  
  if(i&(1<<j)) num++;    

}

先看 1<<j求出来的究竟是什么,从 0到4, 1<<j 的值为: 1, 10, 100, 1000, 10000 (每次都是这样)

而 i 的值呢? 从 0 到 1111,这时的 i 与 上五个不同值的(1<<j),得到的num表示 i 中有多少个 1, 如果 (i&(1<<j)) == true 的话,那么这时就说明 有 1 在 j 这个位置

i 所在的for结束后,那么纸牌的全部替换的情况都遍历了,尽管第一次可能替换你1张牌,第二次却替换你2张牌,第三次却又替换了你的1张牌,但位置时不同的,思考一下就会知道所有的情况在用上位运算后就很完美的处理掉了!

然后你要做的:

处理现在在你手中的牌,给牌排序,关键字有两个,牌值得大小和牌的花色,基数排序没必要,我就用了以前的方式,排完牌值大小的基础上再处理花色的问题。但在排牌之前最好先处理一下用字符代表牌的方式,转换成数字,比如说A=1, T=10,  k=13; C = 1,  S = ... 用类型为整型的二维数组存储一下,这样相对比较简单

牌的顺序排好后,这时就要看判断符合上面给的情况的那种了:

这就意味着要写8个判断的函数了(最后一种情况不要了,默认为最后一种情况),每个函数根据返回的值是1或0来判断

这样处理下去大概就差不多了, 需要注意的是:判断是否为顺子的时候,A可以放在第一位,也可以放在最后(即K的后面)

PS:

这次出的题目考虑得全面,并没有让做题者有疑惑或难堪的地方

  1 #include<iostream>
  2 #include<cstring>
  3 #include<algorithm>
  4 using namespace std;
  5 char poke[12][4], temp[12][4];
  6 int transfer[6][2];
  7 char output[10][20];
  8 int res;
  9 
 10 void memset_1(char (*des)[4], char (*src)[4])
 11 {
 12     for(int i=0; i<10; i++)
 13     strcpy(des[i], src[i]);
 14     return;
 15 }
 16 
 17 int  prior(char elem)
 18 {
 19     if('2'<= elem && elem <= '9') return (elem - '0');
 20     switch(elem)
 21     {
 22         case 'A' : return 1;
 23         case 'T' : return 10;
 24         case 'J' : return 11;
 25         case 'Q' : return 12;
 26         case 'K' : return 13;
 27         
 28         case 'C' : return 1;
 29         case 'D' : return 2;
 30         case 'H' : return 3;
 31         case 'S' : return 4;
 32     }
 33     return -1;
 34 }
 35 
 36 void swap_1(int left, int right)
 37 {
 38     int sw[2];
 39     sw[0] = transfer[left][0];
 40     sw[1] = transfer[left][1];
 41     transfer[left][0] = transfer[right][0];
 42     transfer[left][1] = transfer[right][1];
 43     transfer[right][0] = sw[0];
 44     transfer[right][1] = sw[1];
 45     return;
 46 }
 47 
 48 void basesort()
 49 {
 50     for(int i=0; i<5; ++i)
 51     {
 52         for(int j=0; j<=1; ++j)
 53         transfer[i][j] = prior(temp[i][j]);
 54     }
 55     for(int i=0; i<4; ++i)
 56     {
 57         int flag = 0;
 58         for(int j=0; j<4-i; ++j)
 59         if(transfer[j][0] > transfer[j+1][0])
 60         {
 61             swap_1(j, j+1);
 62             flag = 1;
 63         }
 64         if(!flag) break;
 65     }
 66     for(int part1=0, part2=0, i=0; i<5; i++)
 67     {
 68         if(i+1<5 && transfer[i][0] == transfer[i+1][0])
 69             part2++;
 70         else
 71         {
 72             for(int t=0; t<part2-part1; ++t)
 73             {
 74                 int flag = 0;
 75                 for(int j=part1; j<part2-t; ++j)
 76                 if(transfer[j][1] > transfer[j+1][1])
 77                 {
 78                     swap_1(j, j+1);
 79                     flag = 1;
 80                 }
 81                 if(!flag) break;
 82             }
 83             part1 = part2 = i+1;
 84         }
 85     }
 86     return;
 87 }
 88 
 89 void Print()
 90 {
 91     for(int i=0; i<5; ++i)
 92     cout<<temp[i]<<" ";
 93     return;
 94 }
 95 
 96 int is_straight_flush()
 97 {
 98     int flag = 1;
 99     for(int i=1; i<5; ++i)
100     {
101         if(transfer[i-1][0]+1 != transfer[i][0] || transfer[i-1][1] != transfer[i][1])
102         {
103             flag = 0;
104             break;
105         }
106     }
107     if(flag) return 1;
108     else 
109     {
110         if(transfer[0][0] == 1 && transfer[1][0] == 10 && transfer[0][1] == transfer[1][1])
111         {
112             flag = 1;
113             for(int i=2; i<5; ++i)
114             if(transfer[i-1][0]+1 != transfer[i][0] || transfer[i-1][1] != transfer[i][1])
115             {
116                 flag = 0;
117                 break;
118             }
119         }
120         return flag;
121     }
122 }
123 
124 int is_four()
125 {
126     for(int i=0; i<=1; ++i)
127     {
128         int flag = 1;
129         for(int j=i+1; j<4+i; ++j)
130         {
131             if(transfer[j][0] != transfer[j-1][0])
132             {
133                 flag = 0;
134                 break;
135             }
136         }
137         if(flag) return 1;
138     }
139     return 0;
140     
141 }
142 
143 int is_full()
144 {
145     if(transfer[0][0] == transfer[1][0] && transfer[3][0] == transfer[4][0])
146     {
147         if(transfer[1][0] == transfer[2][0] || transfer[2][0] == transfer[3][0])
148         return 1;    
149     }
150     return 0;
151 }
152 
153 int is_flush()
154 {
155     for(int i=1; i<5; ++i)
156     if(transfer[i-1][1] != transfer[i][1])
157         return 0;
158     return 1;
159 }
160 
161 int is_straight()
162 {
163     int flag = 1;
164     for(int i=1; i<5; ++i)
165     if(transfer[i-1][0]+1 != transfer[i][0])
166     {
167         flag = 0;
168         break;
169     } 
170     if(flag) return 1;
171     else
172     {
173         if(transfer[0][0] == 1 && transfer[1][0] == 10)
174         {
175             flag = 1;
176             for(int i=2; i<5; ++i)
177             if(transfer[i-1][0] != transfer[i][0])
178             {
179                 flag = 0;
180                 break;
181             }
182         }
183         return flag;
184     }
185 }
186 
187 int is_three()
188 {
189     for(int i=0; i<=2; ++i)
190     {
191         if(transfer[i][0] == transfer[i+1][0] && transfer[i+1][0] == transfer[i+2][0]) 
192         return 1;
193     }
194     return 0;
195 }
196 
197 int is_two()
198 {
199     if(transfer[0][0] == transfer[1][0])
200     {
201         if(transfer[2][0] == transfer[3][0] || transfer[3][0] == transfer[4][0])
202         return 1;
203     }
204     if(transfer[1][0] == transfer[2][0] && transfer[3][0] == transfer[4][0])
205         return 1;
206     return 0;
207 }
208 
209 int is_one()
210 {
211     for(int i=0; i<=3; ++i)
212     {
213         if(transfer[i][0] == transfer[i+1][0]) return 1;
214     }
215     return 0;
216 }
217 
218 void Traverse()
219 {
220     basesort();
221     
222     if(is_straight_flush())    {res = 0; return;}
223     if(is_four())              {res = 1; return;}
224     if(is_full())              {res = res < 2 ? res : 2; return;}
225     if(is_flush())             {res = res < 3 ? res : 3; return;}
226     if(is_straight())          {res = res < 4 ? res : 4; return;}
227     if(is_three())             {res = res < 5 ? res : 5; return;}
228     if(is_two())               {res = res < 6 ? res : 6; return;}
229     if(is_one())               {res = res < 7 ? res : 7; return;}
230 }
231 
232 void memset_2()
233 {
234     strcpy(output[0], "straight-flush");
235     strcpy(output[1], "four-of-a-kind");
236     strcpy(output[2], "full-house");
237     strcpy(output[3], "flush");
238     strcpy(output[4], "straight");
239     strcpy(output[5], "three-of-a-kind");
240     strcpy(output[6], "two-pairs");
241     strcpy(output[7], "one-pair");
242     strcpy(output[8], "highest-card");
243 }
244 
245 int main()
246 {
247 /*  freopen("input.txt", "r", stdin);
248     freopen("output.txt", "w", stdout);
249 */
250     int sequence[6];
251     for(int r=0; r<6; r++) sequence[r] = r+1;
252     memset_2();
253     while(cin>>poke[0])
254     {
255         for(int i=2; i<=10; ++i)
256             cin>>poke[i-1];
257         res = 8;
258         for(int i=0; i<(1<<5); ++i)
259         {
260             int num = 0;
261             memset_1(temp, poke);
262             for(int j=0; j<5; ++j)
263             if(i&(1<<j)) num++;
264             sort(sequence, sequence+6);
265             int cnt=0;
266             for(int j=0; j<5; ++j)
267             if(i&(1<<j)) strcpy(temp[j], temp[(sequence[cnt++]+4)]);
268             Traverse();
269             if(res == 0) break;
270         }
271         cout<<"Hand: ";
272         for(int i=0; i<5; ++i)
273         cout<<poke[i]<<" ";
274         cout<<"Deck: ";
275         for(int i=5; i<10; ++i)
276         cout<<poke[i]<<" ";
277         cout<<"Best hand: "; 
278         cout<<output[res]<<endl;
279     }
280     return 0;
281 }

 

posted @ 2013-04-15 16:59  Gifur  阅读(617)  评论(0编辑  收藏  举报
TOP