题目链接:Who is better?
题意:
两个人玩游戏,游戏规则如下:
有一堆个数为n的石子,游戏双方轮流取石子,满足:
- 先手不能在第一次把所有的石子取完;
- 之后每次可以取的石子数介于1到对手刚取的石子数的2倍之间(包含1和对手刚取的石子数的2倍)。
- 约定取走最后一个石子的人为赢家,求必败态。
现在给你 m 行 a 和 b 表示 n ≡ b (mod a)。
让你求出 n 。之后根据求出的 n 判断
先手赢输出 “Lbnb!”
先手输输出 “Zgxnb!”
n 不存在输出 “Tankernb!”
思路:
- 题目就是裸的斐波那契博弈,裸得不能再裸了,然后重点就是求 n ,但是求 n 就又是裸的拓展中国剩余定理······就很无语
斐波那契博弈:斐波那契博弈
#include<iostream>
#include<cstdio>
#include<cstring>
#include<cstdlib>
#include<cmath>
#include<algorithm>
#include<queue>
#include<stack>
#include<vector>
#include<map>
#include<set>
#include<unordered_map>
#define inf 0x3f3f3f3f
using namespace std;
typedef long long ll;
const int N = 1010;
int n;
ll m[N],a[N];
ll exgcd(ll a, ll b, ll &x, ll &y)
{
if(b == 0)
{
x=1, y = 0;
return a;
}
ll ret = exgcd(b, a % b, y, x);
y -= (a / b) * x;
return ret;
}
ll work()
{
ll M = m[1], A = a[1], t, d, x, y;
for(int i = 2; i <= n; i++)
{
d = exgcd(M, m[i], x, y);
if((a[i] - A) % d) return -1;
x *= (a[i] - A) / d, t = m[i] / d, x = (x % t + t) % t;
A = M * x + A, M = M / d * m[i], A %= M;
}
A = (A % M + M) % M;
return A;
}
int main()
{
scanf("%d", &n);
for(int i = 1; i <= n; i++)
{
scanf("%lld %lld", &m[i], &a[i]);
}
ll ans = work();
if(ans == -1)
{
printf("Tankernb!\n");
}
else
{
ll pre1 = 0;
ll pre2 = 1;
ll sum = 0;
while(sum < ans)
{
sum = pre1 + pre2;
pre1 = pre2;
pre2 = sum;
}
if(sum == ans)
{
printf("Lbnb!\n");
}
else
{
printf("Zgxnb!\n");
}
}
return 0;
}