fzu 2275 Game [第八届福建省大学生程序设计竞赛 Problem D]

题意: 对一个数字有两种操作: (1) 反转, (2) 除以 10 取整. 给你A, B两个数,Alice只能操作数字A,Bob只能操作数字B,如果Alice或Bob执行某次操作后A = B, Alice赢,否则就永远执行下去。

我的思路是a串和b串的后缀0都是无效的,因为经过有限次的操作之和后缀0是可以去掉的,比如100,可以通过操作1或操作2变成1。那么分几种情况讨论一下 在讨论前先把后缀0都去了,如果去了后缀0之后长度为0则说明这个串的元素就只有一个0,那么这个0不可以删除,就给它补回去  。下面开始讨论1.lenb>lena时alice不会赢,因为此时Bob可以一直执行操作1 2.lenb<=lena,用kmp或hash判断一下b串或b的翻转串是否是a串的子串,如果有一个满足,alice就可以通过操作1和操作2达到和b串相等,还有一个需要特判一下,就是b串=="0"时,不管a串是什么都可以变化到”0“,alice也可以赢,然后其他情况都是Bob赢了。

一组比较特殊的数据10 1000

#include<cstdio>
#include<cstring>
#include<string>
#include<iostream>

using namespace std;
#define cas(t) int t; scanf("%d",&t);
const int maxn = 1e5 + 10;
char A[maxn],B[maxn];
int next[maxn];

void getnext(int lent,char *f){
    int i = 0,j = -1;
    next[i] = -1;
    while(i < lent){
        if(j == -1 || f[i] == f[j])
            i ++,j ++, next[i] = j;
        else
            j = next[j];
    }
}

bool kmp(int lens,int lent,char *f){
    for(int i = 0;i < lent + 10;i ++) next[i] = 0;
    getnext(lent,f);
    int i = 0,j = 0;
    while((i < lens) && (j < lent)){
        if(j == -1 || A[i] == f[j])
            i ++,j ++;
        else
            j = next[j];
    }
    if(j == lent) return 1;
    return 0;
}

int main()
{
    cas(t);
    while(t --){
        scanf("%s %s",A,B);
        int lenb = strlen(B);
        int lena = strlen(A);
        for(int i=lena-1;i>=0;i--)
        {
            if(A[i]!='0')
                break;
            else
                A[i]=0;
        }
         for(int i=lenb-1;i>=0;i--)
        {
            if(B[i]!='0')
                break;
            else
                B[i]=0;
        }
        lenb = strlen(B);
        lena = strlen(A);
        if(lena==0)
            A[0]='0';
        if(lenb==0)
            B[0]='0';
        lenb = strlen(B);
        lena = strlen(A);
        if(lena < lenb){       //情况1
            cout<<"Bob"<<endl;
            continue;
        }
        char C[maxn] = {0};
        int p = 0;
        for(int i = lenb - 1;i >= 0;i --)
            C[p ++] = B[i];
       // cout<<A<<endl<<B<<endl<<C<<endl<<lena<<endl<<lenb<<endl<<p<<endl;
        if(B[0]=='0'||kmp(lena,lenb,B) != 0||kmp(lena,p,C) != 0)//情况2
            printf("Alice
");
        else 
            printf("Bob
");
    }
    return 0;
}
原文地址:https://www.cnblogs.com/eason9906/p/11754926.html