結果
問題 | No.2848 Birthday Hit and Blow |
ユーザー | tko919 |
提出日時 | 2024-06-13 14:29:23 |
言語 | C++17 (gcc 12.3.0 + boost 1.83.0) |
結果 |
AC
|
実行時間 | 1,058 ms / 2,000 ms |
コード長 | 10,404 bytes |
コンパイル時間 | 2,204 ms |
コンパイル使用メモリ | 211,068 KB |
実行使用メモリ | 24,964 KB |
平均クエリ数 | 459.50 |
最終ジャッジ日時 | 2024-07-17 02:36:37 |
合計ジャッジ時間 | 3,844 ms |
ジャッジサーバーID (参考情報) |
judge2 / judge4 |
(要ログイン)
テストケース
テストケース表示入力 | 結果 | 実行時間 実行使用メモリ |
---|---|---|
testcase_00 | AC | 31 ms
24,812 KB |
testcase_01 | AC | 1,058 ms
24,964 KB |
ソースコード
// #line 1 "library/Template/template.hpp" #include <bits/stdc++.h> using namespace std; #define rep(i,a,b) for(int i=(int)(a);i<(int)(b);i++) #define rrep(i,a,b) for(int i=(int)(b-1);i>=(int)(a);i--) #define ALL(v) (v).begin(),(v).end() #define UNIQUE(v) sort(ALL(v)),(v).erase(unique(ALL(v)),(v).end()) #define SZ(v) (int)v.size() #define MIN(v) *min_element(ALL(v)) #define MAX(v) *max_element(ALL(v)) #define LB(v,x) int(lower_bound(ALL(v),(x))-(v).begin()) #define UB(v,x) int(upper_bound(ALL(v),(x))-(v).begin()) using ll=long long int; using ull=unsigned long long; using i128=__int128_t; using u128=__uint128_t; const int inf = 0x3fffffff; const ll INF = 0x1fffffffffffffff; template<typename T>inline bool chmax(T& a,T b){if(a<b){a=b;return 1;}return 0;} template<typename T>inline bool chmin(T& a,T b){if(a>b){a=b;return 1;}return 0;} template<typename T,typename U>T ceil(T x,U y){assert(y!=0); if(y<0)x=-x,y=-y; return (x>0?(x+y-1)/y:x/y);} template<typename T,typename U>T floor(T x,U y){assert(y!=0); if(y<0)x=-x,y=-y; return (x>0?x/y:(x-y+1)/y);} template<typename T>int popcnt(T x){return __builtin_popcountll(x);} template<typename T>int topbit(T x){return (x==0?-1:63-__builtin_clzll(x));} template<typename T>int lowbit(T x){return (x==0?-1:__builtin_ctzll(x));} // #line 2 "library/Utility/fastio.hpp" // #include <unistd.h> // namespace fastio { // static constexpr uint32_t SZ = 1 << 17; // char ibuf[SZ]; // char obuf[SZ]; // char out[100]; // // pointer of ibuf, obuf // uint32_t pil = 0, pir = 0, por = 0; // struct Pre { // char num[10000][4]; // constexpr Pre() : num() { // for (int i = 0; i < 10000; i++) { // int n = i; // for (int j = 3; j >= 0; j--) { // num[i][j] = n % 10 | '0'; // n /= 10; // } // } // } // } constexpr pre; // inline void load() { // memmove(ibuf, ibuf + pil, pir - pil); // pir = pir - pil + fread(ibuf + pir - pil, 1, SZ - pir + pil, stdin); // pil = 0; // if (pir < SZ) // ibuf[pir++] = '\n'; // } // inline void flush() { // fwrite(obuf, 1, por, stdout); // por = 0; // } // void rd(char &c) { // do { // if (pil + 1 > pir) // load(); // c = ibuf[pil++]; // } while (isspace(c)); // } // void rd(string &x) { // x.clear(); // char c; // do { // if (pil + 1 > pir) // load(); // c = ibuf[pil++]; // } while (isspace(c)); // do { // x += c; // if (pil == pir) // load(); // c = ibuf[pil++]; // } while (!isspace(c)); // } // template <typename T> void rd_real(T &x) { // string s; // rd(s); // x = stod(s); // } // template <typename T> void rd_integer(T &x) { // if (pil + 100 > pir) // load(); // char c; // do // c = ibuf[pil++]; // while (c < '-'); // bool minus = 0; // if constexpr (is_signed<T>::value || is_same_v<T, i128>) { // if (c == '-') { // minus = 1, c = ibuf[pil++]; // } // } // x = 0; // while ('0' <= c) { // x = x * 10 + (c & 15), c = ibuf[pil++]; // } // if constexpr (is_signed<T>::value || is_same_v<T, i128>) { // if (minus) // x = -x; // } // } // void rd(int &x) { // rd_integer(x); // } // void rd(ll &x) { // rd_integer(x); // } // void rd(i128 &x) { // rd_integer(x); // } // void rd(uint &x) { // rd_integer(x); // } // void rd(ull &x) { // rd_integer(x); // } // void rd(u128 &x) { // rd_integer(x); // } // void rd(double &x) { // rd_real(x); // } // void rd(long double &x) { // rd_real(x); // } // template <class T, class U> void rd(pair<T, U> &p) { // return rd(p.first), rd(p.second); // } // template <size_t N = 0, typename T> void rd_tuple(T &t) { // if constexpr (N < std::tuple_size<T>::value) { // auto &x = std::get<N>(t); // rd(x); // rd_tuple<N + 1>(t); // } // } // template <class... T> void rd(tuple<T...> &tpl) { // rd_tuple(tpl); // } // template <size_t N = 0, typename T> void rd(array<T, N> &x) { // for (auto &d : x) // rd(d); // } // template <class T> void rd(vector<T> &x) { // for (auto &d : x) // rd(d); // } // void read() {} // template <class H, class... T> void read(H &h, T &...t) { // rd(h), read(t...); // } // void wt(const char c) { // if (por == SZ) // flush(); // obuf[por++] = c; // } // void wt(const string s) { // for (char c : s) // wt(c); // } // void wt(const char *s) { // size_t len = strlen(s); // for (size_t i = 0; i < len; i++) // wt(s[i]); // } // template <typename T> void wt_integer(T x) { // if (por > SZ - 100) // flush(); // if (x < 0) { // obuf[por++] = '-', x = -x; // } // int outi; // for (outi = 96; x >= 10000; outi -= 4) { // memcpy(out + outi, pre.num[x % 10000], 4); // x /= 10000; // } // if (x >= 1000) { // memcpy(obuf + por, pre.num[x], 4); // por += 4; // } else if (x >= 100) { // memcpy(obuf + por, pre.num[x] + 1, 3); // por += 3; // } else if (x >= 10) { // int q = (x * 103) >> 10; // obuf[por] = q | '0'; // obuf[por + 1] = (x - q * 10) | '0'; // por += 2; // } else // obuf[por++] = x | '0'; // memcpy(obuf + por, out + outi + 4, 96 - outi); // por += 96 - outi; // } // template <typename T> void wt_real(T x) { // ostringstream oss; // oss << fixed << setprecision(15) << double(x); // string s = oss.str(); // wt(s); // } // void wt(int x) { // wt_integer(x); // } // void wt(ll x) { // wt_integer(x); // } // void wt(i128 x) { // wt_integer(x); // } // void wt(unsigned int x) { // wt_integer(x); // } // void wt(ull x) { // wt_integer(x); // } // void wt(u128 x) { // wt_integer(x); // } // void wt(double x) { // wt_real(x); // } // void wt(long double x) { // wt_real(x); // } // template <class T, class U> void wt(const pair<T, U> val) { // wt(val.first); // wt(' '); // wt(val.second); // } // template <size_t N = 0, typename T> void wt_tuple(const T t) { // if constexpr (N < std::tuple_size<T>::value) { // if constexpr (N > 0) { // wt(' '); // } // const auto x = std::get<N>(t); // wt(x); // wt_tuple<N + 1>(t); // } // } // template <class... T> void wt(tuple<T...> tpl) { // wt_tuple(tpl); // } // template <class T, size_t S> void wt(const array<T, S> val) { // auto n = val.size(); // for (size_t i = 0; i < n; i++) { // if (i) // wt(' '); // wt(val[i]); // } // } // template <class T> void wt(const vector<T> val) { // auto n = val.size(); // for (size_t i = 0; i < n; i++) { // if (i) // wt(' '); // wt(val[i]); // } // } // void print() { // wt('\n'); // } // template <class Head, class... Tail> void print(Head &&head, Tail &&...tail) { // wt(head); // if (sizeof...(Tail)) // wt(' '); // print(forward<Tail>(tail)...); // } // void __attribute__((destructor)) _d() { // flush(); // } // } // namespace fastio // using fastio::flush; // using fastio::print; // using fastio::read; #ifdef LOCAL #define show(...) _show(0, #__VA_ARGS__, __VA_ARGS__) #else #define show(...) true #endif template <typename T> void _show(int i, T name) { cerr << '\n'; } template <typename T1, typename T2, typename... T3> void _show(int i, const T1 &a, const T2 &b, const T3 &...c) { for (; a[i] != ',' && a[i] != '\0'; i++) cerr << a[i]; cerr << ":" << b << " "; _show(i + 1, a, c...); } // template <class T, class U> // ostream &operator<<(ostream &os, const pair<T, U> &p) { // os << "P(" << p.first << ", " << p.second << ")"; // return os; // } // template <typename T, template <class> class C> // ostream &operator<<(ostream &os, const C<T> &v) { // os << "["; // for (auto d : v) // os << d << ", "; // os << "]"; // return os; // } int month[]={-1,31,29,31,30,31,30,31,31,30,31,30,31}; using P=pair<int,int>; P HitBlow(string& s,string& t){ int num[10]={}; int H=0,B=0; rep(i,0,4)if(s[i]==t[i])H++; rep(i,0,4)num[s[i]-'0']++; rep(i,0,4)B+=num[t[i]-'0']; B-=H; return {H,B}; } string exact; P ask(string& s){ cout<<"? "<<s<<endl; int H,B; cin>>H>>B; assert(H!=-1); // auto [H,B]=HitBlow(s,exact); return {H,B}; } void solve(){ // cin>>exact; vector<string> cand; rep(mm,1,13){ rep(dd,1,month[mm]+1){ string add; if(mm<=9)add+="0"; add+=to_string(mm); if(dd<=9)add+="0"; add+=to_string(dd); cand.push_back(add); } } auto best=[&]()->string{ int score=inf; string ret; rep(x,0,10){ rep(y,0,10)if(x!=y){ rep(z,0,10)if(x!=z and y!=z){ rep(w,0,10)if(x!=w and y!=w and z!=w){ string que=to_string(1000*x+100*y+10*z+w); while(SZ(que)<4)que.insert(que.begin(),'0'); int cur[25]={}; for(auto& c:cand){ auto [H,B]=HitBlow(que,c); cur[H*5+B]++; } int mx=0; rep(x,0,25)chmax(mx,cur[x]); if(chmin(score,mx)){ ret=que; } } } } } return ret; }; auto squeeze=[&](string& s,P HB)->void{ vector<string> nxt; for(auto& c:cand){ if(HitBlow(s,c)==HB){ nxt.push_back(c); } } swap(cand,nxt); }; string start="4521"; P HB=ask(start); squeeze(start,HB); while(SZ(cand)>1){ string s=best(); HB=ask(s); squeeze(s,HB); // show(SZ(cand)); } assert(SZ(cand)==1); cout<<"! "<<cand[0]<<endl; int ret; cin>>ret; assert(ret==0); } int main(){ int T; cin>>T; while(T--)solve(); return 0; }