公式

I - 簡易オマハポーカー / Easy Omaha 解説 by KoD


それぞれのプレイヤーが作ることのできるハンドは高々 \({}_4 \mathrm{C}_2 \times {}_5 \mathrm{C}_3 = 60\) 通り です。これらを全て試し、\(n_i\) が最大になるハンド (複数あるならば、\(c_i\) が辞書順最小になるもの) を全てのプレイヤーについて求めておきます。

二人のプレイヤーについて、どちらのハンドが優れているかは \(O(1)\) で判定できます。よって全ての二人組を調べることで、それぞれのプレイヤーについて自分のハンドが他の何人のプレイヤーのハンドよりも優れているかを数えることができます。したがって、\(O(N^2)\) でこの問題を解くことができます。

詳細は以下の実装例を参考にしてください。

#include <bits/stdc++.h>
using namespace std;

pair<int, char> best(const string& s) {
    map<char, int> map;
    for (const char c : s) {
        map[c] += 1;
    }
    int n = 0;
    char c = '?';
    for (const auto& [c_, n_] : map) {
        if (n < n_) {
            n = n_;
            c = c_;
        }
    }
    return {n, c};
}

bool compare(const pair<int, int>& a, const pair<int, int>& b) {
    if (a.first == b.first) {
        return a.second < b.second;
    }
    return a.first > b.first;
}

int main() {
    int N;
    cin >> N;
    string X;
    cin >> X;
    vector<pair<int, char>> B(N);
    for (int i = 0; i < N; ++i) {
        string S;
        cin >> S;
        B[i] = {0, '?'};
        for (int a = 0; a < 4; ++a) {
            for (int b = 0; b < a; ++b) {
                for (int c = 0; c < 5; ++c) {
                    for (int d = 0; d < c; ++d) {
                        string s = "";
                        s += S[a];
                        s += S[b];
                        for (int k = 0; k < 5; ++k) {
                            if (k != c and k != d) {
                                s += X[k];
                            }
                        }
                        auto cand = best(s);
                        if (compare(cand, B[i])) {
                            B[i] = cand;
                        }
                    }
                }
            }
        }
    }
    for (int i = 0; i < N; ++i) {
        bool ok = true;
        for (int j = 0; j < N; ++j) {
            if (i == j) {
                continue;
            }
            if (B[i] == B[j] and j < i) {
                ok = false;
            }
            if (compare(B[j], B[i])) {
                ok = false;
            }
        }
        if (ok) {
            cout << i + 1 << '\n';
        }
    }
    return 0;
}

投稿日時:
最終更新: