結果
問題 | No.2768 Password Crack |
ユーザー |
|
提出日時 | 2024-05-31 23:07:09 |
言語 | C++23 (gcc 13.3.0 + boost 1.87.0) |
結果 |
AC
|
実行時間 | 79 ms / 2,000 ms |
コード長 | 2,097 bytes |
コンパイル時間 | 1,845 ms |
コンパイル使用メモリ | 140,800 KB |
実行使用メモリ | 25,220 KB |
平均クエリ数 | 924.20 |
最終ジャッジ日時 | 2024-12-21 01:27:44 |
合計ジャッジ時間 | 5,614 ms |
ジャッジサーバーID (参考情報) |
judge5 / judge2 |
(要ログイン)
ファイルパターン | 結果 |
---|---|
sample | AC * 1 |
other | AC * 29 |
ソースコード
#include <iostream>#include <vector>#include <map>#include <algorithm>#include <random>#include <cassert>using namespace std;using ll = long long;constexpr int iINF = 1'000'000'000;constexpr ll llINF = 1'000'000'000'000'000'000;void solve (int N) {// AAA..Aを送り付ける// BAA..Aを送り付ける// ABA..Aを送り付ける// -> N回でAの場所を特定できる。// というわけで、A~Yまでを2500回以内で特定できて、ハッピーというわけです。vector<vector<int>> idx(26);map<int, bool> found;int query = 0;vector<int> normal(26);for (int i = 0; i < 26; i++) {vector<char> S(N, (char)(i + 'a'));query++;assert(query <= 2500);cout << "? ";for (auto c : S) cout << c;cout << endl;cin >> normal[i];if (normal[i] == N) {for (int j = 0; j < N; j++) {found[j] = true;idx[i].push_back(j);}continue;}}random_device rd;vector<int> ord(25);for (int i = 0; i < 25; i++) ord[i] = i;shuffle(ord.begin(), ord.end(), rd);for (auto i : ord) {for (int j = 0; j < N; j++) {// 回数節約if (found.find(j) != found.end()) {continue;}vector<char> S(N, (char)(i + 'a'));S[j] = (char) (i + 'a' + 1);query++;assert(query <= 2500);cout << "? ";for (auto c : S) cout << c;cout << endl;int res; cin >> res;if (res < normal[i]) {idx[i].push_back(j);found[j] = true;}}}vector<char> ans(N, '_');for (int i = 0; i < 26; i++) {for (auto j : idx[i]) ans[j] = (char) (i + 'a');}for (int i = 0; i < N; i++) if (ans[i] == '_') ans[i] = 'z';cout << "! ";for (auto c : ans) cout << c;cout << endl;}int main () {int N; cin >> N;solve(N);}