String Game【ZSTUOJ--4212】

Description

Alice and Bob are playing the following game with strings of letters.

Before the game begins, an initial string and a target string are decided. The initial string is at least as long as the target string. Then, Alice and Bob take turns, starting with the initial string. Bob goes first. In each turn, the current player removes either the first or the last letter of the current string. Once the length of the current string becomes equal to the length of the target string, the game stops. If the string at the end of the game is equal to the target string, Alice wins the game; otherwise Bob wins.

Determine who will win the game if both players are playing optimally.


题意:给你两串字符串a和b,Alice和Bob轮流去掉第一个字符串a的头字母或尾字母,问经过去掉头尾字母后能否得到字符串b,若能得到则Alice赢;否则Bob赢,Bob第一个开始,输出赢家。


分析:刚开始以为是道博弈题,但是由于弱太渣,没推出来233,直到比赛结束看了题解才会这道题难过。题解上的这道题的解不是用的博弈,而是直接用的暴力枚举,当然不是简单的纯暴力,是有规律的安静。据题解知(当然你最好自己推一下,可以发现规律哦生气),当b在a字符串的中间时,Alice肯定会赢,因为不管Bob去头还是去尾,Alice都可以去另一头以保证中间的永远留着,这是b字符串在a字符串中出现一次的情况下,如果b字符串在a字符串中出现了两次,则当这两个字符串在a中关于中间对称且两个字符串位置差不超过2时,不管Bob怎么去,Alice都可以与Bob同方向去掉字母以保证让b字符串留下。具体步骤请见代码。


Input

Each test case starts with N, the number of inputs to process. Each input consists of one line, which contains the initial

string, followed by a space, followed by the target string. Each string consists of only lowercase letters. The total input

length will be less than 500000 characters.

Output

For each input, output the winner, which will either be Alice or Bob.

Sample Input

5
aba b
bab b
aaab aab
xyz mnk
xyz xyz

Sample Output

Alice
Alice
Bob
Bob
Alice

#include <iostream>
#include <cstdio>
#include <cstring>
using namespace std;
char a[500001],b[500001];
int settle()
{
    int len1=strlen(a);
    int len2=strlen(b);
    if(len1<len2)
        return 0;
    int pos=(len1-len2)/2;        //b字符串在a字符串中可能出现的中间位置
    int flag;
    if(len1%2==len2%2)            //a字符串与b字符串长度同奇偶时
    {
        flag=1;
        for(int i=0; i<len2; i++) //b字符串在a字符串中只出现一次
            if(b[i]!=a[pos+i])
            {
                flag=0;
                break;
            }
        if(flag)
            return 1;
        flag=1;
        for(int i=0; i<len2; i++)  //b字符串在a字符串中出现两次
            if(b[i]!=a[pos+i+1])
            {
                flag=0;
                break;
            }
        for(int i=0; i<len2; i++)
            if(b[i]!=a[pos+i-1])
            {
                flag=0;
                break;
            }
    }
    else                            //a字符串与b字符串长度奇偶不同时
    {
        flag=1;
        for(int i=0; i<len2; i++)
            if(b[i]!=a[pos+i])
            {
                flag=0;
                break;
            }
        for(int i=0; i<len2; i++)
            if(b[i]!=a[pos+i+1])
            {
                flag=0;
                break;
            }
    }
    return flag;
}
int main()
{
    int t;
    scanf("%d",&t);
    while(t--)
    {
        scanf("%s %s",a,b);
        printf("%s",settle()?"Alice\n":"Bob\n");
    }
    return 0;
}


  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值