2011-09-09 14:49:16Morris

c103. The Psychic Poker Player

c103. The Psychic Poker Player

內容 :

有一種常見的撲克牌遊戲叫"梭哈"(就是你在電影賭神中常見的那種遊戲),每個人各發給5張牌,然後根據牌的花色或點數的組合,給予不同等級的名稱例如:同花順,2對等等。

現 在有一個類似的遊戲,一個玩家先發給5張牌,然後桌上另有5張牌。玩家的5張牌是打開的,而桌上的5張牌是蓋著的。玩 家可以換掉手上的牌0~5張(換的時候按桌上的牌的順序來更換),所以他當然希望換牌之後能得到最好的牌。由於桌上的牌是蓋著的,一般人是無法知道牌的內 容的,所以他必須依照機率來決定該換掉哪些牌。但是在這個問題中,我們的玩家具有特異功能,就是他能看穿桌上那5張蓋著的牌。因此他可以明確的知道該換掉 哪些牌以得到最好的結果。你的任務就是寫一個程式來指點他該換掉哪些牌,使得最後手上的牌等級最高。以下簡單介紹梭哈中由高到低各等級牌的名稱:

  • Straight flush: (中文翻譯:同花順)5張牌同一花色(flush),並且形成一個順子(straight)。例如:8H 9H TH JH QH

  • Four of a kind:(中文翻譯:4條或鐵枝)4張牌同一個點數。例如:8H 8D 8C 8S 9D 

  • Full House:(中文翻譯:葫蘆)3張同一點數,另2張同一點數。例如:8H 8D 8C 7S 7D

  • Flush:(中文翻譯:同花)5張牌同一花色。例如:6H 9H TH JH QH

  • Straight:(中文翻譯:順子)5張牌的點數為連續的。例如:8S 9H TH JH QD。請注意,A是比較特別的:點數T J Q K A是順子,A 2 3 4 5也是順子,而 J Q K A 2不是順子。

  • Three of a kind:(中文翻譯:3條)3張牌同一個點數,另2張牌不同點數。例如:8H 8D 8C AH 9D

  • Two pairs:(中文翻譯:2對)有2組2張牌同一個點數,另1張牌不同點數。例如:8H 8D 5C 5H 9D

  • One pair:(中文翻譯:1對)有2張牌同一個點數,另3張牌皆不同點數。例如:8H 8D KC 5H 2D

  • High Card:(中文翻譯:不知道,就是最爛的就是了)沒有以上任何情況就屬於high card。例如:AH 9D 7C 3H 2D

輸入說明 :

每組測試資料一 列,有10張牌。前5張為玩家一開始手上的5張牌,後5張為桌上蓋著的5張牌。每張牌以2個字元代表,第一個字元為點數(A=Ace, 2-9, T=10, J=Jack, Q=Queen, K=King),第二個字元為花色(C=Clubs, D=Diamonds, H=Hearts, S=Spades)。牌與牌之間有一空白,並且輸入的10張牌一定是合法的。也就是不會有重複的牌出現。

輸出說明 :

對每組測試 資料先輸出玩家一開始手上的那5張牌,然後輸出桌上那5張牌。然後輸出經過換牌(0~5張)之後所產生最好的牌的等級。輸出格式請參考Sample Output。Sample Output 9組測試資料的結果就是梭哈由高到低的9個等級。另外請注意:玩家手上的5張牌順序是沒有意義的,是不重要的。但是桌上的5張牌順序卻是重要的,例如:如 果你要換掉手上的2張牌的話,一定要用桌上牌的前2張去換才行。

範例輸入 :

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

範例輸出 :

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

提示 :

* Luck 貓翻譯

出處 :

ACM 131



作法 : 模擬

/**********************************************************************************/
/*  Problem: c103 "The Psychic Poker Player" from ACM 131                         */
/*  Language: C                                                                   */
/*  Result: AC(4ms, 216KB) judge by this@ZeroJudge                                */
/*  Author: morris1028 at 2011-09-09 14:41:04                                     */
/**********************************************************************************/


#include<stdio.h>
#include<string.h>
#include<stdlib.h>
#define Swap(x, y) {int t; t = x, x = y, y = t;}
char Hand[5][3], Deck[5][3], flag;

int mask[15][4];
void Count() {
    memset(mask, 0, sizeof(mask));
    int i, t1, t2;
    for(i = 0; i < 5; i++) {
        switch(Hand[i][0]) {
            case '2'...'9': t1 = Hand[i][0]-'0';break;
            case 'T':t1 = 10;break;
            case 'J':t1 = 11;break;
            case 'Q':t1 = 12;break;
            case 'K':t1 = 13;break;
            case 'A':t1 =  1;break;
        }
        switch(Hand[i][1]) {
            case 'C':t2 = 0;break;
            case 'D':t2 = 1;break;
            case 'H':t2 = 2;break;
            case 'S':t2 = 3;break;
        }
        mask[t1][t2] = 1;
        if(t1 == 1)    mask[14][t2] = 1;
        /*printf("%s ", Hand[i]);*/
    }/*
    puts("");
    system("pause");*/
}
void Stright_flush() {
    int i, j, k;
    for(i = 0; i < 4; i++) {
        for(j = 1; j <= 10; j++) {
            for(k = j; k <= j+4; k++)
                if(mask[k][i] == 0)    break;
            if(k == j+5) {
                puts("straight-flush"), flag = 1;
                return;
            }
        }
    }
}
void Four_kind() {
    int i, j;
    for(i = 1; i <= 13; i++) {
        for(j = 0; j < 4; j++)
            if(mask[i][j] == 0)    break;
        if(j == 4) {
            puts("four-of-a-kind"),    flag = 1;
            return;
        }
    }
}
void Full_house() {
    int i, j, sum1, sum2, a, b;
    for(i = 1; i <= 13; i++) {
        for(j = 0, sum1 = 0; j < 4; j++)
            sum1 += mask[i][j];
        if(sum1 == 3) {
            for(a = 1; a <= 13; a++) {
                for(b = 0, sum2 = 0; b < 4; b++)
                    sum2 += mask[a][b];
                if(sum2 == 2) {
                    puts("full-house"), flag = 1;
                    return;
                }
            }
        }
    }
}
void Flush() {
    int i, j, sum;
    for(i = 0; i < 4; i++) {
        for(j = 1, sum = 0; j <= 13; j++)
            sum += mask[j][i];
        if(sum == 5) {
            puts("flush"), flag = 1;
            return;
        }
    }
}
void Stright() {
    int i, j, k;
    for(i = 1; i <= 10; i++) {
        for(j = i; j <= i+4; j++)
            if(mask[j][0] || mask[j][1] || mask[j][2] || mask[j][3])
                continue;
            else
                break;
        if(j == i+5) {
            puts("straight"), flag = 1;
            return;
        }
    }
}
void Three_kind() {
    int i, j, sum;
    for(i = 1; i <= 13; i++) {
        for(j = 0, sum = 0; j < 4; j++)
            sum += mask[i][j];
        if(sum == 3) {
            puts("three-of-a-kind"), flag = 1;
            return;
        }
    }
}
void Two_pairs() {
    int i, j, sum1, sum2, a, b;
    for(i = 1; i <= 13; i++) {
        for(j = 0, sum1 = 0; j < 4; j++)
            sum1 += mask[i][j];
        if(sum1 == 2) {
            for(a = 1; a <= 13; a++) {
                if(a != i) {
                        for(b = 0, sum2 = 0; b < 4; b++)
                            sum2 += mask[a][b];
                        if(sum2 == 2) {
                            puts("two-pairs"), flag = 1;
                            return;
                        }
                }
            }
        }
    }
}
void One_pair() {
    int i, j, sum;
    for(i = 1; i <= 13; i++) {
        for(j = 0, sum = 0; j < 4; j++)
            sum += mask[i][j];
        if(sum == 2) {
            puts("one-pair"), flag = 1;
            return;
        }
    }
}
void High_card() {
    puts("highest-card"), flag = 1;
    return;
}
void ( *Function[9])() = {Stright_flush, Four_kind, Full_house, Flush,
                     Stright, Three_kind, Two_pairs, One_pair, High_card};
void Change(int n, int m, int Case) {
    if(flag)
        return;
    if(n == 5) {
        Count();
        ( *Function[Case])();
        return;
    }
    Change(n+1, m, Case);
    Swap(Hand[n][0], Deck[m][0]);Swap(Hand[n][1], Deck[m][1]);
    Change(n+1, m+1, Case);
    Swap(Hand[n][0], Deck[m][0]);Swap(Hand[n][1], Deck[m][1]);
}
main() {
    
    int i;
    while(scanf("%s", &Hand[0]) == 1) {
        for(i = 1; i < 5; i++)
            scanf("%s", &Hand[i]);
        for(i = 0; i < 5; i++)
            scanf("%s", &Deck[i]);
        printf("Hand: ");
        for(i = 0; i < 5; i++)
            printf("%s ", Hand[i]);
        printf("Deck: ");
        for(i = 0; i < 5; i++)
            printf("%s ", Deck[i]);
        printf("Best hand: ");
        for(i = 0, flag = 0; i < 9; i++)
            Change(0, 0, i);
    }
    return 0;
}