Poker Hand Multiplicities
National Olympiad — National round (2010 season)
Submission name: poker.cpp
Problem summary
Four players receive five cards each. Each rank from 2 to 14 occurs four times in the deck. Score hands by their repeated-rank pattern: four of a kind 6, full house 5, three of a kind 4, two pairs 3, one pair 2, all distinct 1. Find the unique winner.
Input
Four rows, each containing the five ranks of one player.
Output
Winning player number and score.
Constraints
Ranks are between 2 and 14; the deal is valid and exactly one player has the highest score.
Worked example
Input and output for the worked example discussed below.
Input
5 2 11 11 4 7 6 9 8 8 8 13 8 13 13 2 9 9 2 14
Output
3 5
Solution analysis
- Count how many times each rank appears in a hand. The actual rank values do not break ties: this problem compares only the six specified multiplicity patterns, not ordinary poker straights or suits.
- Sort the nonzero frequencies in descending order. The largest count distinguishes four-of-a-kind, three-of-a-kind, pairs, and distinct cards. If the largest is 3, inspect whether the next is 2; if it is 2, inspect whether the next is also 2.
- In the example player 3 has frequencies 3 and 2, so scores 5. Player 4 has 2,2,1 and scores 3, while players 1 and 2 score 2. Keep the player whenever its score exceeds the current best.
Why it works
Each valid five-card hand has exactly one of the six integer partitions listed in the statement. Frequency counting recovers that partition exactly, so the decision tree assigns its required score. Taking the maximum identifies the promised unique winner.
Watch out. Do not add ordinary-poker rules. The winner is 1-based. Count distinct ranks, not adjacent equal cards in unsorted input.
Commented C++17 solution
An independently written complete program with standard headers.
#include<algorithm>
#include<iostream>
#include<vector>
using namespace std;
int main(){
int winner=0;
int best=0;
for(int player=1;player<=4;player++){
int frequency[15]={};
for(int card=0;card<5;card++){
int rank;
cin>>rank;
frequency[rank]++;
}
vector<int>groups;
for(int rank=2;rank<=14;rank++){
if(frequency[rank]>0){
groups.push_back(frequency[rank]);
}
}
sort(groups.rbegin(),groups.rend());
int score=1;
// The multiplicity partition completely determines this game's score.
if(groups[0]==4){
score=6;
}
else if(groups[0]==3){
score=groups[1]==2?5:4;
}
else if(groups[0]==2){
score=groups[1]==2?3:2;
}
if(score>best){
best=score;
winner=player;
}
}
cout<<winner<<' '<<best<<'\n';
}