結果
| 問題 |
No.5003 物理好きクリッカー
|
| コンテスト | |
| ユーザー |
|
| 提出日時 | 2018-12-13 19:16:12 |
| 言語 | C++11(廃止可能性あり) (gcc 13.3.0) |
| 結果 |
AC
|
| 実行時間 | 5,956 ms / 10,000 ms |
| コード長 | 8,890 bytes |
| コンパイル時間 | 1,690 ms |
| 実行使用メモリ | 472,528 KB |
| スコア | 320,310,772,365 |
| 平均クエリ数 | 10000.00 |
| 最終ジャッジ日時 | 2021-07-19 09:33:50 |
| 合計ジャッジ時間 | 202,740 ms |
|
ジャッジサーバーID (参考情報) |
judge11 / judge15 |
| 純コード判定しない問題か言語 |
(要ログイン)
| ファイルパターン | 結果 |
|---|---|
| other | AC * 32 |
ソースコード
// 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 = 8.3;
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] = {63, 3, 12, 21, 30, 39};
const int CM = 160 * 2;
struct State{
long c;
long pro;
long pcc;
long bbc;
int bi;
int cmd;
int cmds[CM];
State(){ c = bi = cmd = pcc = bbc = 0; pro = 1; cmds[0] = 0; }
void copy(long _c, long _pro, long _pcc, long _bbc, int _bi, int _cmd){
c = _c;
pro = _pro;
pcc = _pcc;
bbc = _bbc;
bi = _bi;
cmd = _cmd;
}
bool operator<(const State &a) const{
return c != a.c ? c < a.c : pro != a.pro ? pro < a.pro : pcc < a.pcc;
}
void calc_pro(){
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);
}
}
int calc_cnt(){
int r = 0;
for(int i=1; i<FM; i++){
r += (pcc >> bsft[i] & 63);
}
return r;
}
int nextStates(bool bf, bool sf, bool ff, int qi, State vs[], int nqs, int nt){
State &s = vs[nqs++];
int cnt = calc_cnt();
if(cnt >= nt){
int sa = cnt - nt;
int ni = -1;
for(int i=1; i<FM; i++){
if((pcc >> bsft[i] & 63) > sa){
ni = i;
break;
}
sa -= (pcc >> bsft[i] & 63);
}
long bc = bcosts[ni][(pcc >> bsft[ni] & 63) - 1] / 4;
s.copy(c+bc, pro, pcc, bbc, qi, SELL+ni);
s.pcc -= bpls[ni];
s.calc_pro();
if(bf) s.c += s.c / 100;
if(ff){
s.c += s.pro * 7;
}else{
s.c += s.pro;
}
int scc = s.calc_cnt();
if(cnt < scc){
cerr << "ni: " << ni << ", " << cnt << ", " << nt << ", " << scc << endl;
cerr << "moto: ";
for(int i=0; i<FM; i++){
cerr << "(" << (pcc >> bsft[i] & 63) << ", " << (pcc >> asft[i] & 7) << ") ";
}
cerr << endl;
cerr << "aoto: ";
for(int i=0; i<FM; i++){
cerr << "(" << (s.pcc >> bsft[i] & 63) << ", " << (s.pcc >> asft[i] & 7) << ") ";
}
cerr << endl;
}
return nqs;
}
s.copy(c, pro, pcc, bbc, qi, CLICK);
if(bf) s.c += s.c / 100;
if(ff){
s.c += s.pro * 7;
}else{
s.c += s.pro;
}
if(cmds[0] > CM / 2) return nqs;
for(int i=0; i<FM; i++){
if((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){
State &sa = vs[nqs++];
sa.copy(c-ac, pro, pcc, bbc, qi, REF+i);
sa.pcc += apls[i];
sa.calc_pro();
if(bf) sa.c += sa.c / 100;
if(ff){
sa.c += (sa.pro - pow(2, sa.pcc & 7)) * 7;
}else{
sa.c += sa.pro - pow(2, sa.pcc & 7);
}
}
}
if(i==0) continue;
if((pcc >> bsft[i] & 63) < 31){
long bc = bcosts[i][(pcc >> bsft[i] & 63)];
if(sf) bc -= bc / 10;
// else if(c - pro >= bc) continue;
if(c >= bc){
State &sb = vs[nqs++];
sb.copy(c-bc, pro, pcc, bbc + bc, qi, BUY+i);
sb.pcc += bpls[i];
sb.calc_pro();
if(bf) sb.c += sb.c / 100;
if(ff){
sb.c += (sb.pro - pow(2, sb.pcc & 7)) * 7;
}else{
sb.c += sb.pro - pow(2, sb.pcc & 7);
}
}
}
}
return nqs;
}
};
ostream& operator<<(ostream& os, const State& s){
os << "S[" << s.c << ", " << log(s.c) / log(10) << ", bc: " << s.bbc << ", bi: " << s.bi << ", cmd: " << s.cmd << ", ";
os << "P{" << s.pro;
for(int i=0; i<FM; i++){
os << " (" << (s.pcc >> bsft[i] & 63) << ", " << (s.pcc >> asft[i] & 7) << ")";
}
os << "}]";
return os;
}
char S[N];
int R[N];
const int QM = 88000;
const int QMC = QM / 11 - 110;
const int QIM = 4;
State Q[QIM][QM];
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(){
bool sf = 0;
int ft = -1;
Q[0][0] = State();
int nqs = 1;
int cqs = 0;
long etm = 0;
for(int i=0; i<N; i++){
etm += pow(N-i, 2) + N;
}
long etc = 0;
for(int t=0; t<N; t++){
etc += pow(N-t, 2) + N;
double et = TO + starttime - TO * 0.9 * (etm-etc) / etm;
auto &nq = Q[(t+1) % QIM];
auto &cq = Q[t % QIM];
auto &bq = Q[(t-1) % QIM];
cqs = nqs;
nqs = 0;
sort(&cq[0], &cq[cqs]);
bool ff = ft >= t;
bool bf = S[t] == 'B';
int nt = N-t;
nqs = cq[cqs-1].nextStates(bf,sf,ff,cqs-1,nq,nqs,nt);
if(t > 0){
int i = cqs-1;
const auto &bs = bq[cq[i].bi].cmds;
memcpy(cq[i].cmds, bs, (bs[0]+1) * sizeof(bs[0]));
if(cq[i].cmd != CLICK){
cq[i].cmds[++cq[i].cmds[0]] = (t-1) << 5 | cq[i].cmd;
}
}
long mp = cq[cqs-1].pro;
long mx = cq[cqs-1].c + mp * 500;
set<long> pccs;
pccs.clear();
pccs.insert(cq[cqs-1].pcc);
if(t % 1000 == 999){
cerr << t << ": " << cqs << ", " << cq[cqs-1] << endl;
}
int qc = 1;
for(int i=cqs-2; i>=0; i--){
auto qi = cq[i];
bool nf = mx <= qi.c + qi.pro * (N-t-1);
if(nf){
qc++;
if(nf) mx = qi.c + qi.pro * (N-t);
nqs = qi.nextStates(bf,sf,ff,i,nq,nqs,nt);
const auto &bs = bq[cq[i].bi].cmds;
memcpy(cq[i].cmds, bs, (bs[0]+1) * sizeof(bs[0]));
if(cq[i].cmd != CLICK){
cq[i].cmds[++cq[i].cmds[0]] = (t-1) << 5 | cq[i].cmd;
}
if(qc > QMC || GetSeconds() >= et) break;
}
}
sf = 0;
if(S[t] == 'F'){
ft = t + 20;
}else if(S[t] == 'S'){
sf = 1;
}
}
int lqs = nqs;
sort(&Q[N % QIM][0], &Q[N % QIM][lqs]);
int ni = lqs - 1;
for(int i=0; i<N; i++){
R[i] = CLICK;
}
const auto& bs = Q[(N-1) % QIM][Q[N % QIM][ni].bi].cmds;
for(int j=1; j<=bs[0]; j++){
int tn = bs[j] >> 5;
R[tn] = bs[j] & 31;
}
R[N-1] = Q[N % QIM][ni].cmd;
cerr << "ms: " << Q[N % QIM][ni] << 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);
starttime = GetSeconds();
double mainstart = GetSeconds();
cerr << setprecision(10);
init();
cerr << "init_time: " << GetSeconds() - mainstart << endl;
solve();
output();
cerr << "main_time: " << GetSeconds() - mainstart << endl;
return 0;
}