noi.ac 字串游戲

ltdJcoder發表於2022-03-24

題目傳送門

題面

Zhangzj和Owaski在玩一個遊戲。最開始有一個空的01串,Zhangzj和Owaski輪流進行操作,Zhangzj先走。每次進行操作的人可以在串上任意位置加一個新的字元,由於串是01串,新加的字元也只能是“0”或者“1”。

他們事先約定好一個字串\(s\),如果在任意時刻,這個字串包含\(s\)作為它的一個子串,那麼Zhangzj獲勝。現在給定\(s\),假設Zhangzj和Owaski均按照最優策略進行操作,你的任務是判斷Zhangzj能不能在有限時間內獲勝。

題意

A,B輪流往一個初始為空的 \(01\) 串中插入 \(0\)/\(1\), A先手,每次可以插在任意位置。給定一個 \(01\)\(s\), 若某一時刻字串包含 \(s\) 作為它的一個子串, A贏得遊戲。問A是否能在有限時間贏得遊戲。

題解

這種題首先要手玩樣例, 你大概能發現以下結論:
首先,如果B想, 無論A如何操作, B總能在他操作後讓字串變成一個\(01\)間隔的串,
同理,在A操作一次後, 無論B如何操作, A都能讓其變成 \(01\) 間隔串
也就是說, 假如其中一方想, 就可讓這個串始終是 \(01\)間隔串,無論對方怎麼操作

繼續考慮, A如何獲勝? 例如 \(0110\) , A可以通過往 \(010\) 中插入一個 \(1\) 來得到
也就是說, 如果 \(s\) 能通過 \(01\)間隔串加入一個字元得到, 那麼A可以先讓原串先保持 \(01\) 間隔, 等長度足夠時再插入一個字元, A必勝

否則的話, \(s\)不能通過 \(01\)間隔串加 \(1\) 一個字元得到, 那麼B可以讓串始終 \(01\) 間隔, 無法贏

然後就沒有然後了, 考慮如果如果一個串中有超過一個相鄰相同的位置, 那麼就無法得到, 否則一定能

實現

#include <iostream>
#include <cstdio>
using namespace std;

int read(){
    int num=0, flag=1; char c=getchar();
    while(!isdigit(c)) c=getchar();
    while(isdigit(c)) num=num*10+c-'0', c=getchar();
    return num;
}

int n, T;

void reads(){
    int las, cnt=0; char c = getchar();
    while(c!='1' && c!='0') c=getchar();
    las = c, c=getchar();
    while(c=='0' || c=='1') {
        if(c == las) cnt++;
        las = c;
        c=getchar();
    }
    printf(cnt>=2?"Owaski\n":"Zhangzj\n");
}

int main(){
    T = read();
    while(T--) reads();
    return 0;
}

相關文章