第八届福建省大学生程序设计竞赛 FZU 2275 Game(题解+代码)

题目传送门:http://acm.fzu.edu.cn/problem.php?pid=2275
题目:

Game
Problem 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的数字是A,Bob的数字是B。每个回合他们都可以有两个操作:一个是翻转数字,例:x = 123456翻转后为654321。另外是/10操作,例:x = 123456,/10操作之后成为12345(不是12345.6)。他们两人轮流进行一回合,每个人都只能操作自己的数字。如果在任何人的回合之后,两个数字相同,则Alice赢了,否则就继续这个游戏。现在Alice想要知道他是否能在有限的次数内赢得这个比赛或者说这个比赛永远也结束不了。需要注意的是,数据范围应该是到100000而不是10^100000。
题解:如果我们把数字看成字符串的话,我们就会发现这两个操作一个是删除末尾字符,还有一个是翻转字符串,最后要判断的就是两个字符串是否会匹配。所以说这其实就是个kmp模板题。需要注意的就是当B为0的情况。
代码及注释如下:

#include<iostream>
#include<algorithm>
#include<cstring>
using namespace std;
const int maxn = 1e5+5;
char a[maxn],b[maxn];
int nextt[maxn],len_a,len_b;
void get_next() {//求next数组 
	int i = 0,j = -1;
	nextt[i] = j;
	while(i<len_b) {
		if(b[i]==b[j]||j==-1) nextt[++i] = ++j;
		else j = nextt[j];
	}
}
bool kmp() {//kmp算法 
	int i = 0,j = 0;
	get_next();
	while(i<len_a&&j<len_b) {
		if(a[i]==b[j]||j==-1) i++,j++;
		else j = nextt[j];
	}
	if(j==len_b) return true;//匹配成功 
	return false;
}
int main() {
	int T;
	cin>>T;
	while(T--) {
		cin>>a>>b;
		len_a = strlen(a);
		len_b = strlen(b);
		if(b[0]=='0') {//b为0的情况
			cout<<"Alice"<<endl;
			continue;
		}
		if(len_a<len_b) cout<<"Bob"<<endl;
		//a的字符串比b小的话,b可以一直翻转,则游戏会一直继续
		else {
			if(kmp()) cout<<"Alice"<<endl;
			else {
				reverse(a,a+len_a);//翻转之后 
				if(kmp()) cout<<"Alice"<<endl;
				else cout<<"Bob"<<endl;
			}
		}
	}
	return 0;
} 

ac图片

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值