131 – The Psychic Poker PlayerTime limit: 3.000 seconds |
The Psychic Poker Player |
Normally the player cannot see the cards in the deck and so must use probability to decide which cards to discard. In this problem, we imagine that the poker player is psychic and knows which cards are on top of the deck. Write a program which advises the player which cards to discard so as to maximize the value of the resulting hand.
Input and Output
Input will consist of a series of lines, each containing the initial five cards in the hand then the first five cards on top of the deck. Each card is represented as a two-character code. The first character is the face-value (A=Ace, 2-9, T=10, J=Jack, Q=Queen, K=King) and the second character is the suit (C=Clubs, D=Diamonds, H=Hearts, S=Spades). Cards will be separated by single spaces. Each input line will be from a single valid deck, that is there will be no duplicate cards in each hand and deck.
Each line of input should produce one line of output, consisting of the initial hand, the top five cards on the deck, and the best value of hand that is possible. Input is terminated by end of file.
Use the sample input and output as a guide. Note that the order of the cards in the player’s hand is irrelevant, but the order of the cards in the deck is important because the discarded cards must be replaced from the top of the deck. Also note that examples of all types of hands appear in the sample output, with the hands shown in decreasing order of value.
Sample Input
1 2 3 4 5 6 7 8 9 |
TH JH QC QD QS QH KH AH 2S 6S 2H 2S 3H 3S 3C 2D 3D 6C 9C TH 2H 2S 3H 3S 3C 2D 9C 3D 6C TH 2H AD 5H AC 7H AH 6H 9H 4H 3C AC 2D 9C 3S KD 5S 4D KS AS 4C KS AH 2H 3C 4H KC 2C TC 2D AS AH 2C 9S AD 3C QH KS JS JD KD 6C 9C 8C 2D 7C 2H TC 4C 9S AH 3D 5S 2H QD TD 6S KH 9H AD QH |
Sample Output
1 2 3 4 5 6 7 8 9 |
Hand: TH JH QC QD QS Deck: QH KH AH 2S 6S Best hand: straight-flush Hand: 2H 2S 3H 3S 3C Deck: 2D 3D 6C 9C TH Best hand: four-of-a-kind Hand: 2H 2S 3H 3S 3C Deck: 2D 9C 3D 6C TH Best hand: full-house Hand: 2H AD 5H AC 7H Deck: AH 6H 9H 4H 3C Best hand: flush Hand: AC 2D 9C 3S KD Deck: 5S 4D KS AS 4C Best hand: straight Hand: KS AH 2H 3C 4H Deck: KC 2C TC 2D AS Best hand: three-of-a-kind Hand: AH 2C 9S AD 3C Deck: QH KS JS JD KD Best hand: two-pairs Hand: 6C 9C 8C 2D 7C Deck: 2H TC 4C 9S AH Best hand: one-pair Hand: 3D 5S 2H QD TD Deck: 6S KH 9H AD QH Best hand: highest-card |
总体来说进一步刷新了我心目中模拟题的下限。。。
题目样例输出已经从上往下从强到弱给出了各种组合的名称。
具体是这样的:
1 2 3 4 5 6 7 8 9 10 |
straight-flush 5张牌花色相同,点数递增1 four-of-a-kind 5张牌有4张牌点数相同 full-house 5张牌有3张牌点数相同,而且另外2张点数也相同 flush 5张牌花色相同,但是点数没有递增1 straight 5张牌点数递增1,但是花色不同 three-of-a-kind 5张牌有3张点数相同,另外2张点数不同 two-pairs 5张牌有两对牌点数相同 one-pair 5张牌有一对牌点数相同 highest-card 不符合上面任何条件 |
这里也可以利用二进制数来进行状态压缩,然后就各种判断属于什么类型,乍看确实头很大,但是首先可以发现花色和点数是分开判断的,两者之间没有交集,花色也只有全部相同和没有全部相同两种情况,然后点数只有递增1、4张相同、3张相同2张相同、3张相同2张不同、只有两对相同和只有一对相同,其实从上往下一个套一个地判断其实还是蛮容易理清楚的,需要注意的是A 2 3 4 5 和 T J Q K A都是合法递增1,特判一下即可。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 |
/******************************************************** * File Name: uvaoj131.cpp * Author: razrLeLe * Mail: razrlele@gmail.com * Homepage: https://yueyu.io * Created Time: Tue 24 Feb 2015 11:59:50 AM CST ******************************************************/ #include "vector" #include "set" #include "deque" #include "queue" #include "algorithm" #include "functional" #include "iostream" #include "cstdio" #include "cmath" #include "cstdlib" #include "string" #include "cstring" #include "string.h" #include "map" #include "cctype" #include "list" #include "stack" using namespace std; #define INF 0x3f3f3f3f #define LOCAL string hand[5], deck[5], test[5]; int cardnum[14]; char result[9][20]= { "straight-flush", "four-of-a-kind", "full-house", "flush", "straight", "three-of-a-kind", "two-pairs", "one-pair", "highest-card" }; void Drop(int a) { int deckFlag = 0; for(int i = 0; i < 5; i++) { if(a&16) test[i] = hand[i]; else test[i] = deck[deckFlag++]; a <<= 1; } return ; } bool testColor() { for(int i = 0; i < 4; i++) if(test[i][1] != test[i+1][1]) return false; return true; } bool testPoint(int maxn, int minn) { for(int i = minn; i <= maxn; i++) if(!cardnum[i]) return false; if(maxn-minn == 4) return true; return false; } int judge() { memset(cardnum, 0, sizeof(cardnum)); int minn = 15, maxn = 0; for(int i = 0; i < 5; i++) { if(test[i][0] == 'A') cardnum[1]++; else if(test[i][0] == 'T') cardnum[10]++; else if(test[i][0] == 'J') cardnum[11]++; else if(test[i][0] == 'Q') cardnum[12]++; else if(test[i][0] == 'K') cardnum[13]++; else cardnum[test[i][0]-'0']++; } for(int i = 1; i <= 13; i++) { minn = (cardnum[i] && minn>i)?i:minn; maxn = (cardnum[i] && maxn<i)?i:maxn; } bool allsame = testColor(); bool allpoint = testPoint(maxn, minn); //判断类型部分 if(allsame) { if(cardnum[1] && cardnum[10] && cardnum[11] && cardnum[12] && cardnum[13]) return 0; } if(allsame && allpoint) return 0; else if(fabs(cardnum[maxn]-cardnum[minn]) == 3) return 1; else if(fabs(cardnum[maxn]-cardnum[minn]) == 1 && cardnum[maxn]+cardnum[minn] == 5) return 2; else if(allsame) return 3; else if(allpoint) return 4; int countForTwo=0; for(int i = minn; i <= maxn; i++) { if(cardnum[i] == 3) return 5; else if(cardnum[i] == 2) { countForTwo++; if(countForTwo == 2) return 6; } } if(countForTwo) return 7; return 8; } int solve() { int ans = 8; int tmp; for(int i = 0; i < 32; i++) { Drop(i); tmp = judge(); ans = (ans > tmp)? tmp: ans; } return ans; } void simulation() { printf("Hand: "); for(int i = 0; i < 5; i++) printf("%s ", hand[i].c_str()); printf("Deck: "); for(int i = 0; i < 5; i++) printf("%s ", deck[i].c_str()); printf("Best hand: %s\n", result[solve()]); return ; } int main() { #ifdef LOCAL freopen("/home/razrlele/build/data.txt", "r", stdin); freopen("/home/razrlele/build/out.txt", "w", stdout); #endif string in; int inputC = 0; int handnum = 0, decknum = 0; while(cin >> in) { inputC++; if(inputC >= 1 && inputC <= 5) hand[handnum++] = in; else if(inputC >= 6 && inputC < 10) deck[decknum++] = in; else if(inputC == 10) { deck[decknum++] = in; simulation(); inputC = 0; handnum = decknum = 0; } } return 0; } |