Game(KMP)

H - Game
Time Limit:1000MS    Memory Limit:262144KB    64bit IO Format:%I64d & %I64u
use MathJax to parse formulas

Description

Alice and Bob is playing a game.

Each of them has a number. Alice’s number is A, and Bob’s number is B.

Each turn, one player can do one of the following actions on his own number:

1. Flip: Flip the number. Suppose X = 123456 and after flip, X = 654321

2. Divide. X = X/10. Attention all the numbers are integer. For example X=123456 , after this action X become 12345(but not 12345.6). 0/0=0.

Alice and Bob moves in turn, Alice moves first. Alice can only modify A, Bob can only modify B. If A=B after any player’s action, then Alice win. Otherwise the game keep going on!

Alice wants to win the game, but Bob will try his best to stop Alice.

Suppose Alice and Bob are clever enough, now Alice wants to know whether she can win the game in limited step or the game will never end.

Input

First line contains an integer T (1 ≤ T ≤ 10), represents there are T test cases.

For each test case: Two number A and B. 0<=A,B<=10^100000.

Output

For each test case, if Alice can win the game, output “Alice”. Otherwise output “Bob”.

Sample Input

4
11111 1
1 11111
12345 54321
123 123

Sample Output

Alice
Bob
Alice
Alice

Hint

For the third sample, Alice flip his number and win the game.

For the last sample, A=B, so Alice win the game immediately even nobody take a move.

题意:Alice先手 Bob后手 只要Alice和Bob数相等 则Alice胜利 反之Bob
思路:1.当bob的数字是0时,bob必输
2.当bob的数字长度大于alice时 bob必赢
3.反之,当bob的小于alice的时,用kmp看bob是否是alice的子串正查一次,反查一次(如第三组样例就是反查的)


代码:   例如 T=abcabd,那么next[5]表示既是abcab的前缀又是abcab的后缀的串的最长长度,显然应该是2,即串ab。注意到前面的例子中,当发生失配时T回溯到下表2,和next[5]数组是一致的,这当然不是个巧合,事实上,KMP算法就是通过next数组来计算发生失配时模式串应该回溯到的位置。

这里介绍一下next数组的计算方法。

设模式串T[0,m-1],长度为m,由next数组的定义,可知next[0]=next[1]=0,(因为这里的串的后缀,前缀不包括该串本身)。

接下来,假设我们从左到右依次计算next数组,在某一时刻,已经得到了next[0]~next[i],现在要计算next[i+1],设j=next[i],由于知道了next[i],所以我们知道T[0,j-1]=T[i-j,i-1],现在比较T[j]和T[i],如果相等,由next数组的定义,可以直接得出next[i+1]=j+1。

如果不相等,那么我们知道next[i+1]<j+1,所以要将j减小到一个合适的位置po,


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
#include <iostream>
#include<stdio.h>
#include<string.h>
using namespace std;
char a[10000000];
char b[10000000];
char c[10000000];
int next[100010];
void getn(char *b)              //next数组
{
    int len=strlen(b);
    next[0]=next[1]=0;
    for(int i=1;i<len;i++)
    {
        int j=next[i];
        while(j&&b[i]!=b[j])     //一直回溯j直到str[i]==str[j]或j减小到0  
            j=next[j];
        next[i+1]=b[i]==b[j]?j+1:0;
    }
}
int kmp(char *a,char *b)
{
    getn(b);
    int l1=strlen(a),l2=strlen(b);
    int i,j=0,ans=0;
    for(i=0;i<l1;i++)
    {
        while(j&&a[i]!=b[j])         //失配则回溯
            j=next[j];
        if(a[i]==b[j])
            j++;
        if(j==l2)
            break;
    }
    if(j!=l2)
        return 1;
   return 0;
}
int main()
{
    int t,flag;
    cin>>t;
    while(t--)
    {
       scanf("%s %s",&a,&b);
       int l1=strlen(a),l2=strlen(b);
       if(b[0]=='0'&&l2==1)
       {
          printf("Alice\n");
          continue;
       }

       if(l2>l1)
        printf("Bob\n");


       else
       {

           for(int i=0;i<l2;i++)         //用c数组反存b
            c[i]=b[l2-1-i];
            c[l2]='\0';                  //此处务必要加!!
           if(kmp(a,c)==1&&kmp(a,b)==1)   
            printf("Bob\n");
            else
                printf("Alice\n");



       }




    }
    return 0;
}


猜你喜欢

转载自blog.csdn.net/qq_41700151/article/details/80356263
kmp