Skip to content

Instantly share code, notes, and snippets.

@xswang
Last active December 29, 2015 19:48
Show Gist options
  • Save xswang/7719240 to your computer and use it in GitHub Desktop.
Save xswang/7719240 to your computer and use it in GitHub Desktop.
UVaOJ 131 – The Psychic Poker Player 这题一开始以为是搞不定的。之前也没玩过什么扑克,一看这题叙述得这么多,感觉希望渺茫。 解题过程中遇到几个误区,都是把问题想复杂了,也是因为没好好理解题意的原因吧。1,我以为,可以这样:对每一个example来说,先取桌上最顶部替换手中一张,下次可以再从桌上最顶部取一张换掉手中的任何一张(包括刚从桌上取到的),我当时想:我的天,这个 怎么做,太复杂了!实际上,一次只能从桌上的顶部一次取0或几张,至于具体取几张,就要看替换手中牌之后那种情况最大。2,我以为:对于 33334,55552这样的情况,等级是不同的呢,我觉得,55552肯定大于33334吧,而实际上,它俩是同等级的。这样的话,问题又简单了很多,哈哈哈哈..…
#include <iostream>
#include <string.h>
#include <fstream>
#include <algorithm>
using namespace std;
int poker[10],suit[10];
char temppoker[10],tempsuit[10];
void print_result(int &res){
cout<<"Hand: ";
for(int i = 0; i < 5; i++){
cout<<temppoker[i];
cout<<tempsuit[i]<<" ";
}
cout<<"Deck: ";
for(int i = 5; i < 10; i++){
cout<<temppoker[i];
cout<<tempsuit[i]<<" ";
}
cout<<"Best hand: ";
if(res == 0)cout<<"straight-flush"<<endl;
if(res == 1)cout<<"four-of-a-kind"<<endl;
if(res == 2)cout<<"full-house"<<endl;
if(res == 3)cout<<"flush"<<endl;
if(res == 4)cout<<"straight"<<endl;
if(res == 5)cout<<"three-of-a-kind"<<endl;
if(res == 6)cout<<"two-pairs"<<endl;
if(res == 7)cout<<"one-pair"<<endl;
if(res == 8)cout<<"highest-card"<<endl;
}
void judge(int (&tpoker)[10], int (&tsuit)[10], int &maxm){
int straight = 1, flush = 1, pairnum[5];
memset(pairnum, 0,sizeof(pairnum));
for(int i = 0; i < 5; i++)pairnum[i] = 1;
//判断是否同花
for(int i = 0; i < 5; i++)
if(tsuit[i] != tsuit[0]) flush = 0;
//先判断是否为顺子;
for(int i = 0; i < 4; i++)//注意这里不能到5,要到4,不然straight就成了其它的了
if(tpoker[i+1] != (tpoker[i]+1)){straight = 0; break;}
if((tpoker[0] == 1) && (tpoker[1] == 10)
&& (tpoker[2] == 11) && (tpoker[3] == 12) && (tpoker[4] == 13))
straight = 1;
//判断有多少个pair。
int flag[5];
memset(flag, 0, sizeof(flag));
for(int i = 0; i < 5; i++)
for(int j = i+1; j < 5; j++){
if((tpoker[j] == tpoker[i]) && !flag[j]){
flag[j] = 1;
++pairnum[i];
}
}
//对有多少对数排序。
sort(pairnum, pairnum + 5);
//判断分别属于什么类型的牌。
if(flush && straight) {maxm = 0;return;}//同花顺
if(pairnum[4] == 4) {maxm = 1;return;}//有4个相同的
if(pairnum[4] + pairnum[3] == 5) {maxm = 2;return;}//一个为3,一个1对。3+2
if(flush) {maxm = 3;return;}//只有同花
if(straight) {maxm = 4;return;}//只有顺子
if(pairnum[4] == 3 && pairnum[3] == 1) {maxm = 5;return;}//只有一个3张相同。其余为单张
if(pairnum[4] == 2 && pairnum[3] == 2) {maxm = 6;return;}//两对,2+2
if(pairnum[4] + pairnum[3] == 3) {maxm = 7;return;}//一对对子,其中一个为2,其余为1
if(pairnum[4] == 1) {maxm = 8;return;}//最大的为1,也就是都为1
}
int main(){
//ifstream fin;
//fin.open("D:\\C++\\test\\bin\\Debug\\123");
while(cin>>temppoker[0]>>tempsuit[0]){
for(int i = 1; i < 10; i++){
cin>>temppoker[i]>>tempsuit[i];
}
for(int i = 0; i < 10; i++){//将输入的每行中的poker的值改为整数1-13.
if(temppoker[i] == 'A') poker[i] = 1;
else if(temppoker[i] == 'T') poker[i] = 10;
else if(temppoker[i] == 'J') poker[i] = 11;
else if(temppoker[i] == 'Q') poker[i] = 12;
else if(temppoker[i] == 'K') poker[i] = 13;
else poker[i] = temppoker[i] - '0';
}
for(int i = 0; i < 10; i++){
if(tempsuit[i] == 'C') suit[i] = 0;
else if(tempsuit[i] == 'D') suit[i] = 1;
else if(tempsuit[i] == 'H') suit[i] = 2;
else if(tempsuit[i] == 'S') suit[i] = 3;
}
int tpoker[10] ,tsuit[10];
int maxm=0,ranker = 10;
for(int i = 0; i < (1<<5); i++){//对于每种替换方式。
memset(tpoker,0,sizeof(tpoker));
memset(tsuit,0,sizeof(tsuit));
for(int j = 0; j < 10; j++){
tpoker[j] = poker[j];
tsuit[j] = suit[j];
}
int k = 1,t = 1;
for(int j = 0; j < 5; j++){
if(i & (1<<j)){
tpoker[j] = tpoker[4 + k++];//注意这里是4,而不是5.
tsuit[j] = tsuit[4 + t++];//z注意这里是4,而不是5
}//根据1的个数k从顶部取k个替换手中的牌。
}
sort(tpoker,tpoker + 5);//对poker排序,为了便于判断顺子什么的。这里也得到了一个启发:以后再做题时,先排序进行预处理,可以为后续操作带来一定的方便。
judge(tpoker, tsuit,maxm);//判断替换之后手中牌的大小。
if(maxm < ranker)
ranker = maxm;
}
print_result(ranker);
}
return 0;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment