Permalink
Cannot retrieve contributors at this time
Name already in use
A tag already exists with the provided branch name. Many Git commands accept both tag and branch names, so creating this branch may cause unexpected behavior. Are you sure you want to create this branch?
UVA/2.8.2.cpp
Go to fileThis commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
301 lines (244 sloc)
4.81 KB
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#include <iostream> | |
#include <string> | |
#include <algorithm> | |
#include <iomanip> | |
using namespace std; | |
class Hand | |
{ | |
int cards[15]; | |
int suits[4]; // 0 - hearts, 1 - spades, 2 - diamonds, 3 - clubs | |
int rank; | |
public: | |
Hand () { init(); } | |
Hand (const string& hand) | |
{ | |
init(); | |
for (int i = 0; i < 5; ++i) | |
{ | |
++cards[ cardToInt(hand[3*i]) ]; | |
++suits[ suitToInt(hand[3*i+1]) ]; | |
} | |
} | |
int getRank() | |
{ | |
if (is_sf()) | |
return rank; | |
if (is_4k()) | |
return rank; | |
if (is_fh()) | |
return rank; | |
if (is_fl()) | |
return rank; | |
if (is_st()) | |
return rank; | |
if (is_3k()) | |
return rank; | |
if (is_2p()) | |
return rank; | |
if (is_pr()) | |
return rank; | |
rank = 0x100000; | |
int shift = 16; | |
for (int i = 14; i >= 2; i--) { | |
if (cards[i] == 1) { | |
rank += (i << shift); | |
shift -= 4; | |
} | |
} | |
return rank; | |
} | |
private: | |
void init () | |
{ | |
rank = 0; | |
fill (cards, cards+15, 0); | |
fill (suits, suits+4, 0); | |
} | |
int cardToInt (const char c) | |
{ | |
if ('2' <= c && c <= '9') return (c - '0'); | |
else switch (c) { | |
case 'T': return 10; | |
case 'J': return 11; | |
case 'Q': return 12; | |
case 'K': return 13; | |
case 'A': return 14; | |
default: return -1; | |
} | |
} | |
int suitToInt (const char s) | |
{ | |
switch (s) | |
{ | |
case 'H': return 0; | |
case 'S': return 1; | |
case 'D': return 2; | |
case 'C': return 3; | |
default: return -1; | |
} | |
} | |
// Finds a range of consecutive nonzero elements from | |
// array cards and returns the index of the maximum value. | |
// On failure returns -1. | |
int find_range(int length, int value = 1, int start = 14) | |
{ | |
int cnt = 0; | |
for (int i = start; i >= 2+length-1; --i) | |
{ | |
if (cards[i] == value) ++cnt; | |
else cnt = 0; | |
if (cnt == length) return i + length - 1; | |
} | |
return -1; | |
} | |
bool is_sf() | |
{ | |
if (suits[0] != 5 && suits[1] != 5 && suits[2] != 5 && suits[3] != 5) | |
return false; | |
int cnt = 0; | |
for (int i = 14; i >= 2; i--) { | |
if (cards[i]) | |
cnt++; | |
else | |
cnt = 0; | |
if (cnt == 5) { | |
rank = 0x900000 + ((i+4) << 16); | |
return true; | |
} | |
} | |
return false; | |
} | |
bool is_4k() { | |
int four = 0; | |
int one = 0; | |
for (int i = 0; i < 15; i++) { | |
if (cards[i] == 1) | |
one = i; | |
else if (cards[i] == 4) | |
four = i; | |
} | |
if (four) { | |
rank = 0x800000 + (four << 16) + (one << 12); | |
return true; | |
} | |
return false; | |
} | |
bool is_fh() { | |
int three = 0; | |
int two = 0; | |
for (int i = 0; i < 15; i++) { | |
if (cards[i] == 2) | |
two = i; | |
else if (cards[i] == 3) | |
three = i; | |
} | |
if (three && two) { | |
rank = 0x700000 + (three << 16) + (two << 12); | |
return true; | |
} | |
return false; | |
} | |
bool is_fl() { | |
if (suits[0] != 5 && suits[1] != 5 && suits[2] != 5 && suits[3] != 5) | |
return false; | |
rank = 0x600000; | |
int shift = 16; | |
for (int i = 14; i >= 2; i--) { | |
if (cards[i]) { | |
rank += (i << shift); | |
shift -= 4; | |
} | |
} | |
return true; | |
} | |
bool is_st() { | |
int cnt = 0; | |
for (int i = 14; i >= 2; i--) { | |
if (cards[i]) | |
cnt++; | |
else | |
cnt = 0; | |
if (cnt == 5) { | |
rank = 0x500000 + ((i+4) << 16); | |
return true; | |
} | |
} | |
return false; | |
} | |
bool is_3k() { | |
int three = 0; | |
int one[] = { 0, 0 }; | |
for (int i = 0; i < 15; i++) { | |
if (cards[i] == 3) | |
three = i; | |
else if (cards[i] == 1) { | |
if (one[0]) | |
one[1] = i; | |
else | |
one[0] = i; | |
} | |
} | |
if (three) { | |
rank = 0x400000 + (three << 16) + (one[1] << 12) + (one[0] << 8); | |
return true; | |
} | |
return false; | |
} | |
bool is_2p() { | |
int two[] = { 0, 0 }; | |
int one = 0; | |
for (int i = 0; i < 15; i++) { | |
if (cards[i] == 2) { | |
if (two[0]) | |
two[1] = i; | |
else | |
two[0] = i; | |
} | |
else if (cards[i] == 1) | |
one = i; | |
} | |
if (two[0] && two[1]) { | |
rank = 0x300000 + (two[1] << 16) + (two[0] << 12) + (one << 8); | |
return true; | |
} | |
return false; | |
} | |
bool is_pr() { | |
int two = 0; | |
int one[] = { 0, 0, 0 }; | |
for (int i = 0; i < 15; i++) { | |
if (cards[i] == 2) | |
two = i; | |
else if (cards[i] == 1) { | |
if (one[0] && one[1]) | |
one[2] = i; | |
else if (one[0]) | |
one[1] = i; | |
else | |
one[0] = i; | |
} | |
} | |
if (two) { | |
rank = 0x200000 + (two << 16) + (one[2] << 12) + (one[1] << 8) + (one[0] << 4); | |
return true; | |
} | |
return false; | |
} | |
}; | |
int main() | |
{ | |
string line; | |
while (getline(cin, line)) { | |
Hand black(line.substr(0, 14)); | |
Hand white(line.substr(15, 14)); | |
int br = black.getRank(); | |
int wr = white.getRank(); | |
if (br > wr) | |
cout << "Black wins." << endl; | |
else if (wr > br) | |
cout << "White wins." << endl; | |
else | |
cout << "Tie." << endl; | |
} | |
return 0; | |
} |