I believe sorting the poker at first may be helpful. You should determine the kind of the poker hand from the highest rank down to the lowest. Comparing the poker hands with the same kind is tricky to implement due to the complex rules.
Code:
- /*************************************************************************
- * Copyright (C) 2008 by liukaipeng *
- * liukaipeng at gmail dot com *
- *************************************************************************/
- /* @JUDGE_ID 00000 10315 C "Poker Hands" */
- #include <stdio.h>
- #include <stdlib.h>
- #include <string.h>
- #include <strings.h>
- #define NVALUES 13
- #define NSUITS 4
- enum {
- HC, PR, TP, TK, ST, FL, FH, FK, SF,
- };
- void rank(int values[], char suits[], int rank[])
- {
- int i, j;
- int count[NVALUES] = {0};
- int flush;
- int straight;
- int pair = 0;
- int three = 0;
- int four = 0;
- int kind;
- for (i = 0; i < 5; ++i)
- count[values[i]] += 1;
- for (i = 0; i < 5; ++i) {
- for (j = 0; j < 5-i-1; ++j) {
- if (values[j] < values[j+1]) {
- values[j] ^= values[j+1];
- values[j+1] ^= values[j];
- values[j] ^= values[j+1];
- }
- }
- }
- straight = values[0] - values[1] == 1 && values[1] - values[2] == 1 &&
- values[2] - values[3] == 1 && values[3] - values[4] == 1;
- flush = suits[0] == suits[1] && suits[1] == suits[2] &&
- suits[2] == suits[3] && suits[3] == suits[4];
- for (i = 0; i < NVALUES; ++i) {
- if (count[i] == 2)
- pair += 1;
- else if (count[i] == 3)
- three += 1;
- else if (count[i] == 4)
- four += 1;
- }
- if (straight && flush)
- kind = SF;
- else if (four)
- kind = FK;
- else if (three && pair)
- kind = FH;
- else if (flush)
- kind = FL;
- else if (straight)
- kind = ST;
- else if (three)
- kind = TK;
- else if (pair == 2)
- kind = TP;
- else if (pair)
- kind = PR;
- else
- kind = HC;
- rank[0] = kind;
- switch (kind) {
- case HC: case FL:
- for (i = 0; i < 5; ++i)
- rank[i+1] = values[i];
- break;
- case ST: case SF:
- rank[1] = values[0];
- break;
- case FK:
- if (values[0] == values[1])
- rank[1] = values[0];
- else
- rank[1] = values[1];
- break;
- case FH:
- if (values[0] == values[1] && values[1] == values[2])
- rank[1] = values[0];
- else
- rank[1] = values[2];
- break;
- case TK:
- if (values[0] == values[1])
- rank[1] = values[0];
- else if (values[1] == values[2])
- rank[1] = values[1];
- else
- rank[1] = values[2];
- break;
- case PR:
- for (i = 0, j = 2; i < 4; ++i)
- if (values[i] == values[i+1])
- rank[1] = values[i++];
- else
- rank[j++] = values[i];
- break;
- case TP:
- for (i = 0, j = 3; i < 4; ++i)
- if (values[i] == values[i+1])
- rank[1] = values[i++];
- else
- rank[j++] = values[i];
- if (rank[1] < rank[2])
- rank[1] ^= rank[2], rank[2] ^= rank[1], rank[1] ^= rank[2];
- break;
- default:
- break;
- }
- }
- int compare(int bvalues[], char bsuits[], int wvalues[], char wsuits[])
- {
- int brank[6] = {-1, -1, -1, -1, -1, -1, };
- int wrank[6] = {-1, -1, -1, -1, -1, -1, };
- int i;
- rank(bvalues, bsuits, brank);
- rank(wvalues, wsuits, wrank);
- for (i = 0; i < 6; ++i)
- if (brank[i] > wrank[i])
- return 0;
- else if (brank[i] < wrank[i])
- return 1;
- return 2;
- }
- int main(int argc, char *argv[])
- {
- #ifndef ONLINE_JUDGE
- char in[256];
- char out[256];
- strcpy(in, argv[0]);
- strcat(in, ".in");
- freopen(in, "r", stdin);
- strcpy(out, argv[0]);
- strcat(out, ".out");
- freopen(out, "w", stdout);
- #endif
- char *message[] = {
- "Black wins.",
- "White wins.",
- "Tie.",
- };
- char *cvalues = "23456789TJQKA";
- int values[128];
- int bvalues[5], wvalues[5];
- char bsuits[5], wsuits[5];
- char buf[40];
- int i;
- for (i = 0; i < NVALUES; ++i)
- values[cvalues[i]] = i;
- while (fgets(buf, 40, stdin) != NULL) {
- for (i = 0; i < 5; ++i) {
- bvalues[i] = values[buf[3*i]];
- bsuits[i] = buf[3*i+1];
- wvalues[i] = values[buf[3*i+3*5]];
- wsuits[i] = buf[3*i+3*5+1];
- }
- puts(message[compare(bvalues, bsuits, wvalues, wsuits)]);
- }
- return 0;
- }