はまやんはまやんはまやん

hamayanhamayan's blog

Penalty Shoot-out [CodeChef December Challenge 2017 B]

https://www.codechef.com/DEC17/problems/CPLAY
AチームとBチームがPK戦をする。
以下のルールで進めていく

  • AとBが交互にPKをする
  • AがPKをして、BがPKをするのを1セットとする
  • 最初の5セット
    • 普通にPKをする
    • 5セットを終えて、勝利数が多いほうが勝ちとなる
    • もし5セットで引き分けだったばあいはサドンデスとなる
    • なお、この後最適にPKが進んでも5セット終えて勝てないと分かったら、その時点で勝者を決める
  • サドンデス
    • 1セットずつやって勝利数が多くなったら勝者を決める
    • つまり、1セットでどちらかが入ってどちらかが外せば、入った方が勝ち
  • サドンデスでも勝者が決まらなかったら引き分けとなる

どちらが勝つかと、何PK目でそれが分かるかを答えよ(様式は問題参照)。

解法

先頭から順番にシミュレートしていく。
最初の5セットでは、'1'なら点をいれて、勝者が確定したかをチェックを2回やるだけ。
最適にPKが進む場合は自分が全勝して、相手が全敗した場合を考えていけばいい。
 
サドンデスになった場合は、入って外れるまで待ち、入った方を勝者とする。
それでも決まらないなら引き分け。

string S;
//---------------------------------------------------------------------------------------------------
void solve() {
    int a = 0, b = 0;

    rep(i, 0, 5) {
        if (S[i * 2] == '1') a++;
        if (a + 4 - i < b) {
            printf("TEAM-B %d\n", i * 2 + 1);
            return;
        }
        if(b + 5 - i < a) {
            printf("TEAM-A %d\n", i * 2 + 1);
            return;
        }

        if (S[i * 2 + 1] == '1') b++;
        if (b + 4 - i < a) {
            printf("TEAM-A %d\n", i * 2 + 2);
            return;
        }
        if (a + 4 - i < b) {
            printf("TEAM-B %d\n", i * 2 + 2);
            return;
        }
    }

    if (a < b) printf("TEAM-B 10\n");
    else if (a > b) printf("TEAM-A 10\n");
    else {
        rep(i, 5, 10) {
            if (S[i * 2] != S[i * 2 + 1]) {
                if (S[i * 2] == '1') printf("TEAM-A ");
                else printf("TEAM-B ");
                printf("%d\n", i * 2 + 2);
                return;
            }
        }
        printf("TIE\n");
    }
}
//---------------------------------------------------------------------------------------------------
void _main() {
    while (cin >> S) solve();
}