uva 131(枚举子集)
2014-08-11 20:44
211 查看
题意:给出10张牌,前五张牌可以随意舍弃或里留下,后五张牌根据丢弃的个数从前往后依次补齐5张牌,使得最后的5张牌的值最大,牌的值可参照德州扑克大小规则。
题解:枚举出所有5张牌的情况,一共 2^5 - 1 种情况,即从保留5张牌到全部舍弃,可以将这些情况全部拿去判断他的最大值,判断的规则就是德州扑克大小规则。
#include <stdio.h>
#include <string.h>
#include <algorithm>
#include <string>
#include <iostream>
using namespace std;
const int N = 10;
string s
, s1[5];
const string an[9] = {"straight-flush", "four-of-a-kind", "full-house", "flush", "straight", "three-of-a-kind", "two-pairs", "one-pair", "highest-card"};
const string h = "23456789 9JKQT 89JQT 789JT 6789T 2345A AJKQT";
int n, flag, sub[32][5];
void init() {
for (int i = 0; i < N; i++)
s[i] = "";
for (int i = 0; i < 5; i++)
s1[i] = "";
n = 0;
}
int cmp(string a, string b) {
return a < b;
}
int judge() {
sort(s1, s1 + 5, cmp);
int temp = 0;
string tempp = "";
for (int i = 0; i < 5; i++)
tempp += s1[i][0];
if (h.find(tempp) != string::npos)
temp = 1;
if (temp == 1) {
int ttemp = 1;
char c = s1[0][1];
for (int i = 1; i < 5; i++)
if (s1[i][1] == c)
ttemp++;
if (ttemp == 5)
return 0; //同花顺
}
char c1 = s1[0][0];
char c2 = s1[3][0];
char c3 = s1[1][0];
char c4 = s1[4][0];
if (c1 == c2 || c3 == c4)
return 1; //四条
char c5 = s1[2][0];
if ((c1 == c3 && c5 == c4) || (c1 == c5 && c2 == c4))
return 2; //葫芦
int temp1, temp2, temp3, temp4;
temp1 = temp2 = temp3 = temp4 = 0;
for (int i = 0; i < 5; i++) {
if (s1[i][1] == 'H')
temp1++;
else if (s1[i][1] == 'C')
temp2++;
else if (s1[i][1] == 'S')
temp3++;
else
temp4++;
}
if (temp1 == 5 || temp2 == 5 || temp3 == 5 || temp4 == 5)
return 3; //同花
if (temp == 1)
return 4; //顺子
if (c1 == c5 || c3 == c2 || c5 == c4)
return 5; //三条
if ((c1 == c3 && c5 == c2) || (c1 == c3 && c2 == c4) || c3 == c5 && c2 == c4)
return 6; //两对
if (c1 == c3 || c3 == c5 || c5 == c2 || c2 == c4)
return 7; //一对
return 8; //散牌
}
void solve() {
flag = 8;
for (int i = 0; i < (1 << 5); i++) {
for (int j = 0, k = 4; j < 5; j++, k--)
if (i & (1 << j))
sub[i][k] = 1;
else
sub[i][k] = 0;
int temp = 0;
for (int k = 0; k < 5; k++)
s1[k] = "";
for (int k = 0; k < 5; k++) {
if (sub[i][k] == 1) {
s1[temp] += s[k][0];
s1[temp++] += s[k][1];
}
}
for (int k = temp, q = 5; k < 5; k++, q++) {
s1[k] += s[q][0];
s1[k] += s[q][1];
}
int ans = judge();
if (ans < flag)
flag = ans;
}
}
int main() {
char a, b, c;
init();
while (scanf("%c%c%c", &a, &b, &c) != EOF) {
s
+= a;
s[n++] += b;
if (c == '\n') {
solve();
printf("Hand: ");
for (int j = 0; j < 5; j++)
cout << s[j] << " ";
printf("Deck: ");
for (int j = 5; j < N; j++)
cout << s[j] << " ";
printf("Best hand: ");
cout << an[flag] << endl;
init();
}
}
return 0;
}
题解:枚举出所有5张牌的情况,一共 2^5 - 1 种情况,即从保留5张牌到全部舍弃,可以将这些情况全部拿去判断他的最大值,判断的规则就是德州扑克大小规则。
#include <stdio.h>
#include <string.h>
#include <algorithm>
#include <string>
#include <iostream>
using namespace std;
const int N = 10;
string s
, s1[5];
const string an[9] = {"straight-flush", "four-of-a-kind", "full-house", "flush", "straight", "three-of-a-kind", "two-pairs", "one-pair", "highest-card"};
const string h = "23456789 9JKQT 89JQT 789JT 6789T 2345A AJKQT";
int n, flag, sub[32][5];
void init() {
for (int i = 0; i < N; i++)
s[i] = "";
for (int i = 0; i < 5; i++)
s1[i] = "";
n = 0;
}
int cmp(string a, string b) {
return a < b;
}
int judge() {
sort(s1, s1 + 5, cmp);
int temp = 0;
string tempp = "";
for (int i = 0; i < 5; i++)
tempp += s1[i][0];
if (h.find(tempp) != string::npos)
temp = 1;
if (temp == 1) {
int ttemp = 1;
char c = s1[0][1];
for (int i = 1; i < 5; i++)
if (s1[i][1] == c)
ttemp++;
if (ttemp == 5)
return 0; //同花顺
}
char c1 = s1[0][0];
char c2 = s1[3][0];
char c3 = s1[1][0];
char c4 = s1[4][0];
if (c1 == c2 || c3 == c4)
return 1; //四条
char c5 = s1[2][0];
if ((c1 == c3 && c5 == c4) || (c1 == c5 && c2 == c4))
return 2; //葫芦
int temp1, temp2, temp3, temp4;
temp1 = temp2 = temp3 = temp4 = 0;
for (int i = 0; i < 5; i++) {
if (s1[i][1] == 'H')
temp1++;
else if (s1[i][1] == 'C')
temp2++;
else if (s1[i][1] == 'S')
temp3++;
else
temp4++;
}
if (temp1 == 5 || temp2 == 5 || temp3 == 5 || temp4 == 5)
return 3; //同花
if (temp == 1)
return 4; //顺子
if (c1 == c5 || c3 == c2 || c5 == c4)
return 5; //三条
if ((c1 == c3 && c5 == c2) || (c1 == c3 && c2 == c4) || c3 == c5 && c2 == c4)
return 6; //两对
if (c1 == c3 || c3 == c5 || c5 == c2 || c2 == c4)
return 7; //一对
return 8; //散牌
}
void solve() {
flag = 8;
for (int i = 0; i < (1 << 5); i++) {
for (int j = 0, k = 4; j < 5; j++, k--)
if (i & (1 << j))
sub[i][k] = 1;
else
sub[i][k] = 0;
int temp = 0;
for (int k = 0; k < 5; k++)
s1[k] = "";
for (int k = 0; k < 5; k++) {
if (sub[i][k] == 1) {
s1[temp] += s[k][0];
s1[temp++] += s[k][1];
}
}
for (int k = temp, q = 5; k < 5; k++, q++) {
s1[k] += s[q][0];
s1[k] += s[q][1];
}
int ans = judge();
if (ans < flag)
flag = ans;
}
}
int main() {
char a, b, c;
init();
while (scanf("%c%c%c", &a, &b, &c) != EOF) {
s
+= a;
s[n++] += b;
if (c == '\n') {
solve();
printf("Hand: ");
for (int j = 0; j < 5; j++)
cout << s[j] << " ";
printf("Deck: ");
for (int j = 5; j < N; j++)
cout << s[j] << " ";
printf("Best hand: ");
cout << an[flag] << endl;
init();
}
}
return 0;
}
相关文章推荐
- UVA131德州扑克之枚举子集
- uva 131 The Psychic Poker Player(直接枚举)
- UVa 11025 The broken pedometer【枚举子集】
- UVa 1508 Equipment 解题报告(枚举子集)
- UVALive 4794 Sharing Chocolate(状压,枚举子集)
- UVA 11825 Hackers' Crackdown(枚举子集+dp)
- UVA 1151 Buy or Build(最小生成树+枚举子集)
- UVa 1326 - Jurassic Remains(枚举子集+中途相遇法)
- UVA - 1354 Mobile Computing: 枚举二叉树 位运算枚举子集,枚举子集的子集 回溯
- uva 10325 The Lottery 枚举子集+容斥原理
- uva 11088 暴力枚举子集/状压dp
- uva11825(状态压缩+枚举子集)黑客的攻击
- uva 11825 Hackers' Crackdown (状压dp,子集枚举)
- UVA 1508 - Equipment 状态压缩 枚举子集 dfs
- UVA - 131 The Psychic Poker Player (暴力枚举+模拟)
- UVa 1508 - Equipment (状态压缩 + 枚举子集)
- 【UVA】1151 - Buy or Build(二进制枚举子集 + 并查集)
- UVA 11825 Hackers’ Crackdown(集合动态规划 子集枚举)
- uva 11825 - Hackers' Crackdown(dp+子集枚举)
- UVA 1354 Mobile Computing(枚举二叉树+枚举子集)