結果
問題 | No.5003 物理好きクリッカー |
ユーザー | iehn_ |
提出日時 | 2018-12-09 17:30:15 |
言語 | C++11 (gcc 11.4.0) |
結果 |
AC
|
実行時間 | 1,589 ms / 10,000 ms |
コード長 | 8,060 bytes |
コンパイル時間 | 1,776 ms |
実行使用メモリ | 417,480 KB |
スコア | 223,326,457,007 |
平均クエリ数 | 10000.00 |
最終ジャッジ日時 | 2021-07-19 09:13:53 |
合計ジャッジ時間 | 49,403 ms |
ジャッジサーバーID (参考情報) |
judge10 / judge11 |
純コード判定しない問題か言語 |
(要ログイン)
テストケース
テストケース表示入力 | 結果 | 実行時間 実行使用メモリ |
---|---|---|
testcase_00 | AC | 1,513 ms
392,508 KB |
testcase_01 | AC | 1,278 ms
332,084 KB |
testcase_02 | AC | 1,254 ms
319,856 KB |
testcase_03 | AC | 1,281 ms
329,504 KB |
testcase_04 | AC | 1,399 ms
361,796 KB |
testcase_05 | AC | 1,448 ms
381,072 KB |
testcase_06 | AC | 1,231 ms
316,216 KB |
testcase_07 | AC | 1,497 ms
396,144 KB |
testcase_08 | AC | 1,154 ms
287,936 KB |
testcase_09 | AC | 1,488 ms
393,672 KB |
testcase_10 | AC | 1,491 ms
392,564 KB |
testcase_11 | AC | 1,253 ms
329,604 KB |
testcase_12 | AC | 1,216 ms
307,400 KB |
testcase_13 | AC | 1,416 ms
373,464 KB |
testcase_14 | AC | 1,304 ms
337,856 KB |
testcase_15 | AC | 1,302 ms
331,792 KB |
testcase_16 | AC | 1,018 ms
239,996 KB |
testcase_17 | AC | 1,216 ms
305,248 KB |
testcase_18 | AC | 1,454 ms
387,536 KB |
testcase_19 | AC | 1,018 ms
246,104 KB |
testcase_20 | AC | 1,426 ms
373,616 KB |
testcase_21 | AC | 1,459 ms
385,660 KB |
testcase_22 | AC | 1,589 ms
412,616 KB |
testcase_23 | AC | 1,584 ms
417,480 KB |
testcase_24 | AC | 1,336 ms
345,040 KB |
testcase_25 | AC | 1,224 ms
301,720 KB |
testcase_26 | AC | 1,150 ms
287,084 KB |
testcase_27 | AC | 1,385 ms
349,576 KB |
testcase_28 | AC | 1,198 ms
296,172 KB |
testcase_29 | AC | 1,386 ms
364,432 KB |
testcase_30 | AC | 1,135 ms
275,300 KB |
testcase_31 | AC | 1,428 ms
384,524 KB |
ソースコード
// C++11 #include <algorithm> #include <cstdlib> #include <iostream> #include <fstream> #include <vector> #include <cmath> #include "bits/stdc++.h" #include <sys/time.h> #include <emmintrin.h> #include <string> #include <bitset> using namespace std; inline long long GetTSC() { long long lo, hi; asm volatile ("rdtsc": "=a"(lo), "=d"(hi)); return lo + (hi << 32); } inline double GetSeconds() { return GetTSC() / 2.8e9; } struct XorShift { uint64_t x = 88172645463325252ULL; XorShift() {} void setSeed(uint64_t seed) { x = seed; } uint64_t next() { x ^= x << 13; x ^= x >> 7; x ^= x << 17; return x; } int nextInt(int n) { uint64_t upper = 0xFFFFFFFFFFFFFFFFULL / n * n; uint64_t v = next(); while (v >= upper) { v = next(); } return v % n; } double nextDouble() { uint64_t v = next() >> 11; // 53bit return (double)v / (1ULL << 53); } }; const double TO = 9.9; const double eps = 1e-7; const double inf = 1e7; const int N = 10000; const int CLICK = 1; const int FM = 6; const string FS[FM] = {"enhclick", "hand", "lily", "factory", "casino", "grimoire"}; const int FP[FM] = {1, 1, 10, 120, 2000, 25000}; const int FB[FM] = {-1, 150, (int)2e3, (int)3e4, (int)6e5, (int)1e7}; const int FA[FM] = {15, 1500, (int)2e4, (int)3e5, (int)6e6, (int)1e8}; const int BUY = 2; const int SELL = BUY + FM; const int REF = BUY + FM * 2; long bcosts[FM][256]; long acosts[FM][16]; const long amsk[FM] = {7, 7l<<9, 7l<<18, 7l<<27, 7l<<36, 7l<<45}; const long apls[FM] = {1, 1l<<9, 1l<<18, 1l<<27, 1l<<36, 1l<<45}; const int asft[FM] = {0, 9, 18, 27, 36, 45}; const long bmsk[FM] = {0, 63l<<3, 63l<<12, 63l<<21, 63l<<30, 63l<<39}; const long bpls[FM] = {0, 1l<<3, 1l<<12, 1l<<21, 1l<<30, 1l<<39}; const int bsft[FM] = {0, 3, 12, 21, 30, 39}; long calc_pro_pcc(long pcc){ long pro = pow(2, pcc & 7); for(int i=1; i<FM; i++){ pro += FP[i] * (pcc >> bsft[i] & 63) * pow(2, pcc >> asft[i] & 7); } return pro; } vector<tuple<long, long, long, int>> next_states_tp(tuple<long, long, long, int> tp, bool bf, bool sf, bool ff, int qi){ long c = get<0>(tp); long pro = get<1>(tp); long pcc = get<2>(tp); int qi5 = qi << 5; vector<tuple<long, long, long, int>> vs; long sc = c; // FIXME: 忘れてた if(bf) sc += sc / 100; if(ff){ sc += pro * 7; }else{ sc += pro; } vs.emplace_back(sc, pro, pcc, qi5 | CLICK); for(int i=0; i<FM; i++){ if((i<FM-1 || (pcc >> asft[i] & 7) <= (pcc >> asft[i+1] & 7)) && (pcc >> asft[i] & 7) < 7){ long ac = acosts[i][pcc >> asft[i] & 7]; if(sf) ac -= ac / 10; else if(c - pro >= ac) continue; if(c >= ac){ long sac = c - ac; long sapcc = pcc; sapcc += apls[i]; long sapro = calc_pro_pcc(sapcc); if(bf) sac += sac / 100; if(ff){ sac += (sapro - pow(2, sapcc & 7)) * 7; }else{ sac += sapro - pow(2, sapcc & 7); } vs.emplace_back(sac, sapro, sapcc, qi5 | REF+i); } } if(i==0) continue; if((pcc >> bsft[i] & 63) <= ((pcc >> asft[i] & 7) + 1) * 10 && (pcc >> bsft[i] & 63) < 63){ long bc = bcosts[i][(pcc >> bsft[i] & 63)]; if(sf) bc -= bc / 10; else if(c - pro >= bc) continue; if(c >= bc){ long sbc = c - bc; long sbpcc = pcc; sbpcc += bpls[i]; long sbpro = calc_pro_pcc(sbpcc); if(bf) sbc += sbc / 100; if(ff){ sbc += (sbpro - pow(2, sbpcc & 7)) * 7; }else{ sbc += sbpro - pow(2, sbpcc & 7); } vs.emplace_back(sbc, sbpro, sbpcc, qi5 | BUY+i); } } } return vs; } string tpstr(tuple<long, long, long, int> tp){ long sc = get<0>(tp); long spro = get<1>(tp); long spcc = get<2>(tp); int sbicmd = get<3>(tp); ostringstream os; os << "S[" << sc << ", " << log(sc) / log(10) << ", bi: " << (sbicmd >> 5) << ", cmd: " << (sbicmd & 31) << ", "; os << "P{" << spro; for(int i=0; i<FM; i++){ os << " (" << (spcc >> bsft[i] & 63) << ", " << (spcc >> asft[i] & 7) << ")"; } os << "}]"; return os.str(); } char S[N]; int R[N]; vector<tuple<long, long, long, int>> Q[N+1]; double starttime, gt; int tt,ctt; XorShift xs; void init(){ int n; scanf("%d%s", &n, S); for(int i=0; i<FM; i++){ acosts[i][0] = FA[i]; for(int j=1; j<16; j++){ acosts[i][j] = acosts[i][j-1] * 10; } if(i == 0) continue; bcosts[i][0] = FB[i]; for(int j=1; j<256; j++){ long bb = bcosts[i][j-1]; bcosts[i][j] = bb + bb / 5 + (bb % 5 ? 1 : 0); } } } long calc_score(){ long r = 0; return r; } void solve(){ long c = 0; int bcount[FM] = {1, 0, 0, 0, 0, 0}; int acount[FM] = {0, 0, 0, 0, 0, 0}; bool sf = 0; int ft = -1; Q[0].emplace_back(0, 1, 0, 0); for(int t=0; t<N; t++){ auto &nq = Q[t+1]; int cqs = Q[t].size(); sort(&Q[t][0], &Q[t][cqs]); int tc = 0; bool ff = ft >= t; bool bf = S[t] == 'B'; for(const auto &s : next_states_tp(Q[t][cqs-1], bf,sf,ff,cqs-1)){ nq.push_back(s); } long mp = get<1>(Q[t][cqs-1]); long mc = get<2>(Q[t][cqs-1]); if(t % 1000 == 999){ cerr << t << ": " << cqs << ", " << tpstr(Q[t][cqs-1]) << endl; } int qc = 1; for(int i=cqs-2; i>=0; i--){ auto qi = Q[t][i]; long qipro = get<1>(qi); long qipcc = get<2>(qi); if(mp < qipro || (mp == qipro && mc < qipcc)){ qc++; mp = qipro; mc = qipcc; for(const auto &s : next_states_tp(qi, bf,sf,ff,i)){ nq.push_back(s); } if(qc > 1999) break; } } sf = 0; if(S[t] == 'F'){ ft = t + 20; }else if(S[t] == 'S'){ sf = 1; } } int lqs = Q[N].size(); sort(&Q[N][0], &Q[N][lqs]); int ni = lqs - 1; for(int i=N; i>0; i--){ // if(Q[i][ni].cmd != CLICK) cerr << i << ":: " << Q[i][ni] << endl; int bicmd = get<3>(Q[i][ni]); R[i-1] = bicmd & 31; ni = bicmd >> 5; } for(int t=0; t<N; t++){ int tr = R[t]; for(int i=FM-1; i>=0; i--){ long ac = acosts[i][acount[i]]; long bc = bcosts[i][bcount[i]]; if(sf){ ac -= ac / 10; bc -= bc / 10; } if(ac <= c && tr == REF + i){ c -= ac; acount[i]++; break; } if(i > 0 && bc <= c && tr == BUY + i){ c -= bc; bcount[i]++; break; } } R[t] = tr; long cc = 0; if(tr == CLICK){ cc = bcount[0] * pow(2, acount[0]); } for(int i=1; i<FM; i++){ if(bcount[i] < 1) continue; cc += bcount[i] * pow(2, acount[i]) * FP[i]; } if(ft >= t){ cc *= 7; } // if(t % 1000 == 999) cerr << t << ": " << c << ", cc: " << cc << endl; sf = 0; if(S[t] == 'N'){ }else if(S[t] == 'B'){ c += c / 100 + (c%100 ? 1 : 0); }else if(S[t] == 'F'){ ft = t + 20; }else if(S[t] == 'S'){ sf = 1; } c += cc; } for(int i=0; i<FM; i++){ cerr << "i: " << i << " bc: " << bcount[i] << " ac: " << acount[i] << endl; } cerr << "c: " << c << " log: " << log(c) / log(10) << endl; } void output(){ int t = 0; string s; for(int i=0; i<N; i++){ int ri = R[i]; if(ri == CLICK){ cout << "click" << endl; }else if(ri == REF){ cout << "enhclick" << endl; }else if(ri >= BUY && ri < BUY + FM){ cout << "buy " << FS[ri - BUY] << endl; }else if(ri >= REF && ri < REF + FM){ cout << "reinforce " << FS[ri - REF] << endl; }else if(ri >= SELL && ri < SELL + FM){ cout << "sell " << FS[ri - SELL] << endl; } cin >> s; if(i == 0) cerr << "s: " << s << endl; if(s == "-1") return; if(s[0] == '-'){ cerr << 1 / t << endl; } } } int main() { srand((unsigned) time(NULL)); xs.setSeed(rand() % 65536 || 65537); double mainstart = GetSeconds(); cerr << setprecision(10); init(); cerr << "init_time: " << GetSeconds() - mainstart << endl; solve(); output(); cerr << "main_time: " << GetSeconds() - mainstart << endl; return 0; }