1366 - Game
Time Limit: 1s Memory Limit: 256MB
Submissions: 268 Solved: 17
-
Description
- Alice and Bob is playing a game, there N coins in a pile. Alice goes first, she can take away one coin at least, and N-1 coins at most. After that, Bob and Alice move away coins in turn, every time he (she) can take away one to twice of previous one. Assume there are 20 coins, Alice take away 4 coins first, then Bob can take 1 to 8 coins. If Bob takes away 5 coins, then Alice can take 1 to 10 coins next. The one who take the last coin Win. You can suppose that Alice and Bob are so cleaver that they can always do their best to Win. Input
- The first line of the input is an integer T, the number of test cases. For each case, is a line with an integer N, the number of coins. (N < 2 64) Output
- For each case, if Alice lose, just output “Alice Lose”, and if Alice win, please output “Alice Win”, and inform the minimum number of coins Alice should take away in the first turn, as the sample output. Sample Input
-
4 2 5 10 14
Sample Output
-
Alice Lose Alice Lose Alice Win, take 2 coins first Alice Win, take 1 coins first
Hint
-
Source
-
中国地质大学(武汉)第七届ACM程序设计大赛暨华中地区部属高校ACM邀请赛
这题在原有的斐波那契博弈的基础上新增了一些内容。要你求出如果先手要赢。需要拿多少石子。
首先我们还是要先建立斐波那契数列。。。。
但是这题的数据范围有些大。需要用 unsigned long long 才能装下,这也是本题的坑点。数列要建到92左右。
先手如果想赢。就得通过第一手拿的石子,把对方逼入必败态。我们可以用石子数n减去离它最近的那个斐波那契数。得到一个数。如果先手取这个数的石子的话。就能把对方逼入必败态。这个数往往是1或2.我们要通过多次计算。直到石子数减去离它最近的那个斐波那契数等于1或2。
上代码:
#include<cstdio>
#include<cstring>
#include<iostream>
#include<cmath>
#include<algorithm>
using namespace std;
typedef unsigned long long ULL;
ULL num[105];
int main()
{
num[1]=1;
num[2]=2;
for(int i=3; i<93; i++)
{
num[i]=num[i-1]+num[i-2];
}
int t;
cin>>t;
ULL n;
while(t--)
{
scanf("%llu",&n);
ULL bz=n;
int flag=0;
for(int i=92; i>=0; i--)
{
if(num[i]==bz)
{
break;
}
else if(num[i]<bz)
{
bz=bz-num[i];
flag=1;
}
}
if(n==bz&&flag==0)
{
printf("Alice Lose\n");
}
else
{
printf("Alice Win, take %llu coins first\n",bz);
}
}
return 0;
}