結果
問題 | No.2848 Birthday Hit and Blow |
ユーザー |
![]() |
提出日時 | 2024-07-17 02:19:44 |
言語 | C++17 (gcc 13.3.0 + boost 1.87.0) |
結果 |
AC
|
実行時間 | 832 ms / 2,000 ms |
コード長 | 7,767 bytes |
コンパイル時間 | 2,938 ms |
コンパイル使用メモリ | 226,404 KB |
最終ジャッジ日時 | 2025-02-23 16:05:01 |
ジャッジサーバーID (参考情報) |
judge4 / judge2 |
(要ログイン)
ファイルパターン | 結果 |
---|---|
sample | AC * 1 |
other | AC * 1 |
ソースコード
// #define _GLIBCXX_DEBUG// #pragma GCC optimize("O2,unroll-loops")#include <bits/stdc++.h>using namespace std;#define rep(i, n) for (int i = 0; i < int(n); i++)#define per(i, n) for (int i = (n)-1; 0 <= i; i--)#define rep2(i, l, r) for (int i = (l); i < int(r); i++)#define per2(i, l, r) for (int i = (r)-1; int(l) <= i; i--)#define each(e, v) for (auto &e : v)#define MM << " " <<#define pb push_back#define eb emplace_back#define all(x) begin(x), end(x)#define rall(x) rbegin(x), rend(x)#define sz(x) (int)x.size()template <typename T>void print(const vector<T> &v, T x = 0) {int n = v.size();for (int i = 0; i < n; i++) cout << v[i] + x << (i == n - 1 ? '\n' : ' ');if (v.empty()) cout << '\n';}using ll = long long;using pii = pair<int, int>;using pll = pair<ll, ll>;template <typename T>bool chmax(T &x, const T &y) {return (x < y) ? (x = y, true) : false;}template <typename T>bool chmin(T &x, const T &y) {return (x > y) ? (x = y, true) : false;}template <class T>using minheap = std::priority_queue<T, std::vector<T>, std::greater<T>>;template <class T>using maxheap = std::priority_queue<T>;template <typename T>int lb(const vector<T> &v, T x) {return lower_bound(begin(v), end(v), x) - begin(v);}template <typename T>int ub(const vector<T> &v, T x) {return upper_bound(begin(v), end(v), x) - begin(v);}template <typename T>void rearrange(vector<T> &v) {sort(begin(v), end(v));v.erase(unique(begin(v), end(v)), end(v));}// __int128_t gcd(__int128_t a, __int128_t b) {// if (a == 0)// return b;// if (b == 0)// return a;// __int128_t cnt = a % b;// while (cnt != 0) {// a = b;// b = cnt;// cnt = a % b;// }// return b;// }struct Union_Find_Tree {vector<int> data;const int n;int cnt;Union_Find_Tree(int n) : data(n, -1), n(n), cnt(n) {}int root(int x) {if (data[x] < 0) return x;return data[x] = root(data[x]);}int operator[](int i) { return root(i); }bool unite(int x, int y) {x = root(x), y = root(y);if (x == y) return false;// if (data[x] > data[y]) swap(x, y);data[x] += data[y], data[y] = x;cnt--;return true;}int size(int x) { return -data[root(x)]; }int count() { return cnt; };bool same(int x, int y) { return root(x) == root(y); }void clear() {cnt = n;fill(begin(data), end(data), -1);}};template <int mod>struct Mod_Int {int x;Mod_Int() : x(0) {}Mod_Int(long long y) : x(y >= 0 ? y % mod : (mod - (-y) % mod) % mod) {}static int get_mod() { return mod; }Mod_Int &operator+=(const Mod_Int &p) {if ((x += p.x) >= mod) x -= mod;return *this;}Mod_Int &operator-=(const Mod_Int &p) {if ((x += mod - p.x) >= mod) x -= mod;return *this;}Mod_Int &operator*=(const Mod_Int &p) {x = (int)(1LL * x * p.x % mod);return *this;}Mod_Int &operator/=(const Mod_Int &p) {*this *= p.inverse();return *this;}Mod_Int &operator++() { return *this += Mod_Int(1); }Mod_Int operator++(int) {Mod_Int tmp = *this;++*this;return tmp;}Mod_Int &operator--() { return *this -= Mod_Int(1); }Mod_Int operator--(int) {Mod_Int tmp = *this;--*this;return tmp;}Mod_Int operator-() const { return Mod_Int(-x); }Mod_Int operator+(const Mod_Int &p) const { return Mod_Int(*this) += p; }Mod_Int operator-(const Mod_Int &p) const { return Mod_Int(*this) -= p; }Mod_Int operator*(const Mod_Int &p) const { return Mod_Int(*this) *= p; }Mod_Int operator/(const Mod_Int &p) const { return Mod_Int(*this) /= p; }bool operator==(const Mod_Int &p) const { return x == p.x; }bool operator!=(const Mod_Int &p) const { return x != p.x; }Mod_Int inverse() const {assert(*this != Mod_Int(0));return pow(mod - 2);}Mod_Int pow(long long k) const {Mod_Int now = *this, ret = 1;for (; k > 0; k >>= 1, now *= now) {if (k & 1) ret *= now;}return ret;}friend ostream &operator<<(ostream &os, const Mod_Int &p) { return os << p.x; }friend istream &operator>>(istream &is, Mod_Int &p) {long long a;is >> a;p = Mod_Int<mod>(a);return is;}};ll mpow(ll x, ll n, ll mod) {ll ans = 1;x %= mod;while (n != 0) {if (n & 1) ans = ans * x % mod;x = x * x % mod;n = n >> 1;}ans %= mod;return ans;}template <typename T>T modinv(T a, const T &m) {T b = m, u = 1, v = 0;while (b > 0) {T t = a / b;swap(a -= t * b, b);swap(u -= t * v, v);}return u >= 0 ? u % m : (m - (-u) % m) % m;}ll divide_int(ll a, ll b) {if (b < 0) a = -a, b = -b;return (a >= 0 ? a / b : (a - b + 1) / b);}// const int MOD = 1000000007;const int MOD = 998244353;using mint = Mod_Int<MOD>;const int inf = 1e9;// ----- library -------// ----- library -------int main() {ios::sync_with_stdio(false);std::cin.tie(nullptr);cout << fixed << setprecision(15);vector<int> days{31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};vector<string> ts;rep(i, 12) rep(j, days[i]) {int month = i + 1, day = j + 1;string s;s += '0' + (month >= 10 ? month / 10 : 0);s += '0' + month % 10;s += '0' + (day >= 10 ? day / 10 : 0);s += '0' + day % 10;bool ok = true;rep(i, 4) rep2(j, i + 1, 4) if (s[i] == s[j]) ok = false;if (!ok) continue;ts.eb(s);}vector<string> qs;rep(v, 10000) {vector<int> a(4);int cv = v;rep(i, 4) a[i] = cv % 10, cv /= 10;bool ok = true;rep(i, 4) rep2(j, i + 1, 4) if (a[i] == a[j]) ok = false;if (!ok) continue;string s;rep(i, 4) s += '0' + a[i];qs.eb(s);}int D = sz(ts), Q = sz(qs);vector<vector<int>> eval(D, vector<int>(Q, 0));rep(i, D) rep(j, Q) {rep(k, 4) if (ts[i][k] == qs[j][k]) eval[i][j] += 20;rep(k, 4) rep(l, 4) if (k != l && ts[i][k] == qs[j][l]) eval[i][j]++;}auto get = [&](vector<bool> f) {int mi = 1e9, id = -1;rep(j, Q) {vector<int> cnt(100, 0);rep(i, D) if (f[i]) cnt[eval[i][j]]++;if (chmin(mi, *max_element(all(cnt)))) id = j;}return id;};ll base = 5436591, mask = (1LL << 30) - 1;unordered_map<ll, bool> vis;unordered_map<ll, int> memo_q;unordered_map<ll, vector<bool>> memo_f;vis[0] = true;vector<bool> f0(D, true);memo_q[0] = get(f0);memo_f[0] = f0;int T;cin >> T;while (T--) {vector<bool> f = f0;ll hash = 0;rep(i, 6) {int id = memo_q[hash];cout << "? " << qs[id] << endl;int H, B;cin >> H >> B;if (H == -1)exit(1);int v = H * 20 + B;hash = (hash * base + v) & mask;if (vis[hash]) f = memo_f[hash];else {rep(i, D) f[i] = f[i] & (eval[i][id] == v);vis[hash] = true;memo_q[hash] = get(f);memo_f[hash] = f;}}int ans = -1;rep(i, D) if (f[i]) ans = i;cout << "! " << ts[ans] << endl;int ret;cin >> ret;if (ret == -1)exit(1);}}