#include #include #include #include #include using namespace std; int countMatches(const vector& a, const vector& b) { int count = 0; for (int i = 0; i < 5; i++) { if (a[i] == b[i]) { count++; } } return count; } int countWrongPosition(const vector& a, const vector& b) { vector usedA(5, false); vector usedB(5, false); for (int i = 0; i < 5; i++) { if (a[i] == b[i]) { usedA[i] = true; usedB[i] = true; } } int count = 0; for (int i = 0; i < 5; i++) { if (usedA[i]) continue; for (int j = 0; j < 5; j++) { if (usedB[j]) continue; if (a[i] == b[j]) { usedB[j] = true; count++; break; } } } return count; } // 2つの組み合わせ(ソート済み)で共通している数字の個数 int countCommonDigits(const vector& a, const vector& b) { set setA(a.begin(), a.end()); int count = 0; for (int digit : b) { if (setA.count(digit)) { count++; } } return count; } vector chooseBestGuess(const vector>& candidates) { if (candidates.empty()) return {}; return candidates[0]; } vector> generateAllPermutations(const vector& digits) { vector> allPerms; vector perm = digits; sort(perm.begin(), perm.end()); do { allPerms.push_back(perm); } while (next_permutation(perm.begin(), perm.end())); return allPerms; } vector> generateAllCombinations() { vector> allCombs; for (int a = 0; a <= 9; a++) { for (int b = a + 1; b <= 9; b++) { for (int c = b + 1; c <= 9; c++) { for (int d = c + 1; d <= 9; d++) { for (int e = d + 1; e <= 9; e++) { allCombs.push_back({a, b, c, d, e}); } } } } } return allCombs; } int main() { ios_base::sync_with_stdio(false); cin.tie(nullptr); // 組み合わせの候補リスト vector> combCandidates = generateAllCombinations(); // 各組み合わせに対する順列候補 map, vector>> combToPermCandidates; for (const auto& comb : combCandidates) { combToPermCandidates[comb] = generateAllPermutations(comb); } while (true) { // まだ順列が複数ある組み合わせを探す vector chosenComb; for (const auto& comb : combCandidates) { if (combToPermCandidates[comb].size() > 1) { chosenComb = comb; break; } } // なければ適当に1つ選ぶ if (chosenComb.empty() && !combCandidates.empty()) { chosenComb = combCandidates[0]; } if (chosenComb.empty()) break; vector>& permCandidates = combToPermCandidates[chosenComb]; if (permCandidates.empty()) break; vector guess = chooseBestGuess(permCandidates); // 出力 for (int num : guess) { cout << num; } cout << endl; // 30個の応答を受け取る multiset> responses; int count_5_0 = 0; for (int i = 0; i < 30; i++) { int x, y; cin >> x >> y; responses.insert({x, y}); if (x == 5 && y == 0) { count_5_0++; } } // 全て5 0なら終了 if (count_5_0 == 30) { break; } // *** 重要:x+yの値を使って組み合わせ候補を絞る *** vector> newCombCandidates; for (const auto& comb : combCandidates) { // この組み合わせに対して期待されるx+yの値のセットを計算 multiset expectedSums; for (const auto& perm : combToPermCandidates[comb]) { int x = countMatches(guess, perm); int y = countWrongPosition(guess, perm); expectedSums.insert(x + y); } // 実際のx+yのセット multiset actualSums; for (auto [x, y] : responses) { actualSums.insert(x + y); } // または、共通数字で直接チェック multiset expectedCommon; int common = countCommonDigits(guess, comb); // この組み合わせの全順列は同じ共通数字数を持つ for (int i = 0; i < combToPermCandidates[comb].size(); i++) { expectedCommon.insert(common); } // actualSumsにこのcommonが含まれているか bool valid = false; for (int sum : actualSums) { if (sum == common) { valid = true; break; } } if (valid) { newCombCandidates.push_back(comb); } } combCandidates = newCombCandidates; // 現在の組み合わせの順列候補を絞る vector> newPermCandidates; for (const auto& perm : permCandidates) { int x = countMatches(guess, perm); int y = countWrongPosition(guess, perm); // この(x,y)が実際の応答に含まれているか if (responses.count({x, y}) > 0) { newPermCandidates.push_back(perm); } } permCandidates = newPermCandidates; // 候補が1つになったら次の組み合わせへ if (permCandidates.size() <= 1) { // 次の組み合わせを探す } } return 0; }