結果

問題 No.7 プライムナンバーゲーム
ユーザー @abcde@abcde
提出日時 2019-03-10 21:01:06
言語 C++11
(gcc 11.4.0)
結果
AC  
実行時間 143 ms / 5,000 ms
コード長 2,351 bytes
コンパイル時間 1,635 ms
コンパイル使用メモリ 169,924 KB
実行使用メモリ 6,696 KB
最終ジャッジ日時 2024-04-09 04:35:16
合計ジャッジ時間 5,069 ms
ジャッジサーバーID
(参考情報)
judge1 / judge4
このコードへのチャレンジ(β)

テストケース

テストケース表示
入力 結果 実行時間
実行使用メモリ
testcase_00 AC 142 ms
6,692 KB
testcase_01 AC 140 ms
6,692 KB
testcase_02 AC 141 ms
6,688 KB
testcase_03 AC 141 ms
6,688 KB
testcase_04 AC 140 ms
6,692 KB
testcase_05 AC 143 ms
6,692 KB
testcase_06 AC 141 ms
6,692 KB
testcase_07 AC 141 ms
6,692 KB
testcase_08 AC 140 ms
6,688 KB
testcase_09 AC 143 ms
6,692 KB
testcase_10 AC 141 ms
6,696 KB
testcase_11 AC 140 ms
6,692 KB
testcase_12 AC 140 ms
6,692 KB
testcase_13 AC 142 ms
6,692 KB
testcase_14 AC 141 ms
6,688 KB
testcase_15 AC 142 ms
6,692 KB
testcase_16 AC 141 ms
6,696 KB
権限があれば一括ダウンロードができます

ソースコード

diff #

#include <bits/stdc++.h>
using namespace std;

int main() {
    
    // 1. 入力情報取得.
    int N;
    cin >> N;
    
    // 2. 素数を用意する.
    // AtCoder Beginner Contest 084
    // https://atcoder.jp/contests/abc084
    map<int, int> m;
    m[2]++;
    // for(int i = 3; i < 1e4 + 1; i += 2) {
    for(int i = 3; i < 1e4 + 1; i += 2) {
        bool isPrime = true;
        for(int j = 3; j < sqrt(i) + 1; j += 2) {
            if(i % j == 0){
                isPrime = false;
                break;
            }
        }
        if(isPrime) m[i]++;
    }
    // for(auto &p : m) cout << p.first << " " << p.second << endl;
    
    // 3. 手番の勝ちパターンを集計.
    // 3-1. 先手勝ちパターンを集計.
    // -> 素数 に, 2 or 3 or 11 or 12 を加算した数字は, 先手勝ちパターンのはず.
    string ans[10002];
    for(int i = 0; i < 10002; i++) ans[i] = "init";
    ans[0] = "Nobody", ans[1] = "Nobody", ans[2] = "Lose", ans[3] = "Lose", ans[11] = "Lose", ans[12] = "Lose";
    for(int i = 2; i < 9999; i++) if(m[i] > 0) ans[i + 2] = "Win", ans[i + 3] = "Win";
    // for(int i = 0; i < 10002; i++) cout << "ans[" << i << "]=" << ans[i] << endl;
    
    // 3-2. 後手勝ちパターンを集計.
    for(int i = 13; i < 10001; i++){
        if(ans[i] == "Win" || ans[i] == "Lose") continue;
        int isWin = 0;
        for(auto &p : m){
            if(p.first >= i) break;
            int diff = i - p.first;
            // cout << i << " " << p.first << " " << ans[diff] << endl;
            // 先手から後手に手番を渡したときに, 
            // ans[diff] が, 後手勝ちのパターンであれば, 
            // ans[i] は, 先手勝ちパターンのはず.
            // -> p.second > 0 は, p.first が 素数 であることの条件.
            if(diff > 1 && p.second > 0 && ans[diff] == "Lose"){
                isWin++;
                break;
            }
        }
        if(isWin == 0) ans[i] = "Lose";
        if(isWin >  0) ans[i] = "Win";
    }
    // ans[27]=Lose は, 多分正しいはず.
    // for(int i = 0; i < 10002; i++) cout << "ans[" << i << "]=" << ans[i] << endl;
    // for(int i = 0; i < 10002; i++) if(i > 7100) cout << "ans[" << i << "]=" << ans[i] << endl;
    
    // 4. 出力.
    cout << ans[N] << endl;
    return 0;
    
}
0