Editorial for Card Counting
Submitting an official solution before solving the problem yourself is a bannable offence.
Author:
There are too many cards to simply try every set of five cards and see which ones form a full house. So we will need to use some maths to calculate the answer.
Firstly, count how many cards there are of each rank. Suppose there are cards of rank
for each
.
Then, given two ranks , the number of full houses with 3 cards of rank
and 2 cards of rank
is
. Sum over all 182 possible pairs of ranks to get the total number of full houses (which fits in a
long long
).
Finally, the number of hands of five cards is exactly , which also fits in a
long long
. Divide one number by the other to get the desired probability.
Taking in the input is time complexity. While we have to check all possible pairs of cards, we are using a frequency counter to do so, and there is a limited amount (
) possible pairs so the overall time complexity is still
. The solution uses
space as the map representing the card deck can only have up to 13 entries in it.
C++ solution:
#include <bits/stdc++.h>
using namespace std;
int main() {
int n;
cin >> n;
unordered_map<string, int> freqs;
string x;
for (int i = 0; i < n; i++) {
cin >> x;
freqs[x]++;
}
long long numerator = 0;
for (auto [card1, freq1]: freqs) {
for (auto [card2, freq2]: freqs) {
if (card1 == card2 || freq1 < 2 || freq2 < 3) continue;
numerator += 1ll * freq1*(freq1-1)/2 * freq2*(freq2-1)*(freq2-2)/6;
}
}
long long denominator = 1ll * n*(n-1)*(n-2)*(n-3)*(n-4)/120;
cout << (double)numerator/denominator << endl;
}
Python solution:
from collections import Counter
from math import comb
n = int(input())
cards = input().split()
freqs = Counter(cards)
fullhouses = 0
for k1, v1 in freqs.items():
for k2, v2 in freqs.items():
if k1 == k2 or v1 < 2 or v2 < 3:
continue
fullhouses += comb(v1, 2) * comb(v2, 3)
print(fullhouses / comb(n, 5))
Comments