結果

問題 No.5003 物理好きクリッカー
ユーザー maimai
提出日時 2018-12-02 22:40:08
言語 C++17
(gcc 12.3.0 + boost 1.83.0)
結果
AC  
実行時間 56 ms / 10,000 ms
コード長 8,743 bytes
コンパイル時間 2,612 ms
実行使用メモリ 21,996 KB
スコア 736,967,222
平均クエリ数 10000.00
最終ジャッジ日時 2021-07-19 07:59:02
合計ジャッジ時間 6,687 ms
ジャッジサーバーID
(参考情報)
judge11 / judge10
純コード判定しない問題か言語
このコードへのチャレンジ
(要ログイン)

テストケース

テストケース表示
入力 結果 実行時間
実行使用メモリ
testcase_00 AC 54 ms
21,696 KB
testcase_01 AC 54 ms
21,840 KB
testcase_02 AC 54 ms
21,864 KB
testcase_03 AC 54 ms
21,852 KB
testcase_04 AC 53 ms
21,852 KB
testcase_05 AC 53 ms
21,660 KB
testcase_06 AC 54 ms
21,912 KB
testcase_07 AC 54 ms
21,936 KB
testcase_08 AC 54 ms
21,852 KB
testcase_09 AC 54 ms
21,516 KB
testcase_10 AC 54 ms
21,864 KB
testcase_11 AC 54 ms
21,372 KB
testcase_12 AC 55 ms
21,528 KB
testcase_13 AC 55 ms
21,696 KB
testcase_14 AC 53 ms
21,852 KB
testcase_15 AC 53 ms
21,864 KB
testcase_16 AC 53 ms
21,888 KB
testcase_17 AC 53 ms
21,360 KB
testcase_18 AC 56 ms
21,720 KB
testcase_19 AC 55 ms
21,360 KB
testcase_20 AC 54 ms
21,900 KB
testcase_21 AC 55 ms
21,900 KB
testcase_22 AC 53 ms
21,516 KB
testcase_23 AC 53 ms
21,900 KB
testcase_24 AC 52 ms
21,876 KB
testcase_25 AC 54 ms
21,492 KB
testcase_26 AC 52 ms
21,516 KB
testcase_27 AC 54 ms
21,516 KB
testcase_28 AC 53 ms
21,684 KB
testcase_29 AC 54 ms
21,492 KB
testcase_30 AC 54 ms
21,384 KB
testcase_31 AC 53 ms
21,336 KB
権限があれば一括ダウンロードができます
コンパイルメッセージ
main.cpp: 関数 ‘char* machineToString(EMachine)’ 内:
main.cpp:59:9: 警告: ISO C++ forbids converting a string constant to ‘char*’ [-Wwrite-strings]
   59 |         "hand",
      |         ^~~~~~
main.cpp:60:9: 警告: ISO C++ forbids converting a string constant to ‘char*’ [-Wwrite-strings]
   60 |         "lily",
      |         ^~~~~~
main.cpp:61:9: 警告: ISO C++ forbids converting a string constant to ‘char*’ [-Wwrite-strings]
   61 |         "factory",
      |         ^~~~~~~~~
main.cpp:62:9: 警告: ISO C++ forbids converting a string constant to ‘char*’ [-Wwrite-strings]
   62 |         "casino",
      |         ^~~~~~~~
main.cpp:63:9: 警告: ISO C++ forbids converting a string constant to ‘char*’ [-Wwrite-strings]
   63 |         "grimoire"
      |         ^~~~~~~~~~

ソースコード

diff #

#pragma GCC optimize ("O3")
// #pragma GCC target ("avx")
#include "bits/stdc++.h"

using namespace std;
using ll = long long int;

#define debugos cout
#define debug(v) {printf("L%d %s > ",__LINE__,#v);debugos<<(v)<<endl;}
#define debugv(v) {printf("L%d %s > ",__LINE__,#v);for(auto e:(v)){debugos<<e<<" ";}debugos<<endl;}
#define debuga(m,w) {printf("L%d %s > ",__LINE__,#m);for(int x=0;x<(w);x++){debugos<<(m)[x]<<" ";}debugos<<endl;}
#define debugaa(m,h,w) {printf("L%d %s >\n",__LINE__,#m);for(int y=0;y<(h);y++){for(int x=0;x<(w);x++){debugos<<(m)[y][x]<<" ";}debugos<<endl;}}
#define ALL(v) (v).begin(),(v).end()
#define repeat(cnt,l) for(auto cnt=decltype(l)();(cnt)<(l);++(cnt))
#define rrepeat(cnt,l) for(auto cnt=(l)-1;0<=(cnt);--(cnt))
#define iterate(cnt,b,e) for(auto cnt=(b);(cnt)!=(e);++(cnt))
#define diterate(cnt,b,e) for(auto cnt=(b);(cnt)!=(e);--(cnt))
const ll MD = 1000000007ll; const long double PI = 3.1415926535897932384626433832795L;
inline void assert_call(bool assertion, function<void()> f) { if (!assertion) { cerr << "assertion fault:" << endl; f(); abort(); } }
template<typename T1, typename T2> inline ostream& operator <<(ostream &o, const pair<T1, T2> p) { o << '(' << p.first << ':' << p.second << ')'; return o; }
template<typename Vec> inline ostream& _ostream_vecprint(ostream& os, const Vec& a) {
    os << '['; for (const auto& e : a) os << ' ' << e << ' '; os << ']'; return os;
}
template<typename T> inline ostream& operator<<(ostream& o, const vector<T>& v) { return _ostream_vecprint(o, v); }
template<typename T, size_t S> inline ostream& operator<<(ostream& o, const array<T, S>& v) { return _ostream_vecprint(o, v); }
template<typename T> inline T& chmax(T& to, const T& val) { return to = max(to, val); }
template<typename T> inline T& chmin(T& to, const T& val) { return to = min(to, val); }
void bye(string s, int code = 0) { cout << s << endl; exit(code); }
mt19937_64 randdev(8901016);
template<typename T, typename Random = decltype(randdev), typename enable_if<is_integral<T>::value>::type* = nullptr>
inline T rand(T l, T h, Random& rand = randdev) { return uniform_int_distribution<T>(l, h)(rand); }
template<typename T, typename Random = decltype(randdev), typename enable_if<is_floating_point<T>::value>::type* = nullptr>
inline T rand(T l, T h, Random& rand = randdev) { return uniform_real_distribution<T>(l, h)(rand); }


// 


enum EMachine {
    kHand = 0, kLily, kFactory, kCasino, kGrimoire, kClicker
};

enum ECommand {
    kClick = 0,
    kBuy,
    kReinforce
};

enum EEffect {
    kNothing = 0,
    kBonus,
    kFever,
    kSale
};


inline char* machineToString(EMachine m) {
    static char* s[] = {
        "hand",
        "lily",
        "factory",
        "casino",
        "grimoire"
    };
    return s[(int)m];
}


inline EEffect charToEffect(char c) {
    return
        c == 'N' ? EEffect::kNothing :
        c == 'B' ? EEffect::kBonus :
        c == 'F' ? EEffect::kFever :
        c == 'S' ? EEffect::kSale : EEffect::kNothing;
}


//


struct Action {
    ECommand command;
    EMachine target;
    Action(ECommand aCommand = ECommand::kClick, EMachine aTarget = EMachine::kHand)
        :command(aCommand), target(aTarget) {
    }

    void print() const {
        switch (command)
        {
        case kClick:
            cout << "click" << endl;
            break;
        case kBuy:
            cout << "buy " << machineToString(target) << endl;
            break;
        case kReinforce:
            if (target == EMachine::kClicker)
                cout << "enhclick" << endl;
            else
                cout << "reinforce " << machineToString(target) << endl;
            break;
        default:
            clog << "invalid command\n";
            break;
        }
    }
};


class State {

    ll wallet_;
    array<int, 6> numMachine_;
    array<int, 6> lvlMachine_;
    array<ll, 5> costBuyMachine_ = { 150, 2000, 30000, 60000, 10000000 };
    array<ll, 6> costRfMachine_ = { 1500, 20000, 300000, 600000, 100000000, 15 };

public:

    State() :wallet_(0) {
        numMachine_.fill(0);
        numMachine_[5] = 1;
        lvlMachine_.fill(0);
    }

    //
    inline ll costBuyMachine(EMachine e) const {
        return costBuyMachine_[(int)e];
    }
    inline ll costReinforceMachine(EMachine e) const {
        return costRfMachine_[(int)e];
    }
    inline ll wallet() const {
        return wallet_;
    }
    inline int countOfMachine(EMachine e) const {
        return numMachine_[(int)e];
    }

    //
    inline ll efficiency(EMachine e) const {
        const ll s[] = { 1, 10, 120, 2000, 25000, 1 };
        return s[(int)e] * (1ll << lvlMachine_[(int)e])*numMachine_[(int)e];
    }

    void applyAction(Action act, EEffect eff) {
        if (act.command == ECommand::kClick) {
        }
        else if (act.command == ECommand::kBuy) {
            numMachine_[act.target] += 1;
            wallet_ -= costBuyMachine_[act.target];
            costBuyMachine_[act.target] = (costBuyMachine_[act.target] * 6 + 4) / 5;
        }
        else if (act.command == ECommand::kReinforce) {
            lvlMachine_[act.target] += 1;
            wallet_ -= costRfMachine_[act.target];
            costRfMachine_[act.target] = (costRfMachine_[act.target] * 10);
        }
        ll fever = eff == EEffect::kFever ? 7 : 1;
        for (int i = 4 + (act.command == ECommand::kClick); i >= 0; --i) {
            wallet_ += efficiency((EMachine)i);
        }

        if (eff == EEffect::kBonus) {
            wallet_ += (wallet_ + 99) / 100;
        }
    }

};


//


namespace IN {
    const int maxTurnCount = 10000;
    EEffect effects[maxTurnCount];
}


//


void convertinput(const string& l) {

    using namespace IN;
    int fever = 0;
    int sale = 0;
    repeat(i, maxTurnCount) {
        auto e = charToEffect(l[i]);
        effects[i] = e == EEffect::kBonus ? EEffect::kBonus : EEffect::kNothing;
        if (fever > 0) {
            --fever;
            effects[i] = EEffect::kFever;
        }
        if (sale > 0) {
            --sale;
            effects[i] = EEffect::kSale;
        }
        if (e == EEffect::kFever) {
            fever = 20;
        }
        else if (e == EEffect::kSale) {
            sale = 1;
        }
    }
}


void generateInput() {
    using namespace IN;

    string l; l.reserve(maxTurnCount);
    int next = rand(0, 200);
    repeat(i, maxTurnCount) {
        if (next > 0) {
            --next;
            l.push_back('N');
        }
        else {
            l.push_back("DFS"[rand(0, 2)]);
            next = rand(100, 200);
        }
    }
    convertinput(l);
}


void scan() {
    using namespace IN;
    int n;
    cin >> n;
    assert(maxTurnCount == n);
    string l;
    cin >> l;

    convertinput(l);
}


//


namespace Solver {


    void renda(State& state, int currentTurnCount) {
        for (; currentTurnCount < IN::maxTurnCount; ++currentTurnCount) {
            state.applyAction(Action(ECommand::kClick), IN::effects[currentTurnCount]);
        }
    }


    void solve() {

        State state;

        array<Action, IN::maxTurnCount> stackedActions;
        pair<ll, int> bestWalletTurn(0,0);

        repeat(turncount, IN::maxTurnCount) {

            Action action(ECommand::kClick);

            rrepeat(m, 5) {
                if (state.countOfMachine((EMachine)m) == 0 ||
                    state.costBuyMachine((EMachine)m) < state.costReinforceMachine((EMachine)m)) {
                    if (state.costBuyMachine((EMachine)m) <= state.wallet()) {
                        action = Action(ECommand::kBuy, (EMachine)m);
                    }
                }
                else {
                    if (state.costReinforceMachine((EMachine)m) <= state.wallet()) {
                        action = Action(ECommand::kReinforce, (EMachine)m);
                    }
                }
            }

            if (turncount > IN::maxTurnCount*2 / 3) {
                State s = state;
                renda(s, turncount);
                chmax(bestWalletTurn, make_pair(s.wallet(), turncount));
            }

            // action.print();
            stackedActions[turncount] = action;
            state.applyAction(action, IN::effects[turncount]);
        }

        repeat(i, bestWalletTurn.second) {
            stackedActions[i].print();
        }
        iterate(i, bestWalletTurn.second, IN::maxTurnCount) {
            Action(ECommand::kClick).print();
        }

    }

}


int main() {
    using namespace IN;

    scan();
    //generateInput();

    Solver::solve();

    repeat(i, maxTurnCount) {
        string str;
        cin >> str;
        if (str == "-3" || str == "-4") abort();
        //assert(str == "ok");
    }

    return 0;
}
0