描述
题解
看似是博弈论,其实最后能够被选取的点数只有 ngcd(a,b) ,那么我们只需要再判一下奇偶性即可了。这个题用来测试 GCD 模版刚刚好。
测试代码
One:GCD最大公约数
// AC 模版通过
#include <iostream>
using namespace std;
int n, a, b;
int gcd(int x, int y)
{
if (!x || !y)
{
return x > y ? x : y;
}
for (int t; t = x % y, t; x = y, y = t) ;
return y;
}
int main(int argc, const char * argv[])
{
int T;
cin >> T;
int res;
for (int i = 1; i <= T; i++)
{
cin >> n >> a >> b;
res = gcd(a, b);
if ((n / res) & 1)
{
printf("Case #%d: Yuwgna\n", i);
}
else
{
printf("Case #%d: Iaka\n", i);
}
}
return 0;
}
Two:快速GCD
// AC 模版通过
#include <iostream>
using namespace std;
int n, a, b;
int kgcd(int a, int b)
{
if (a == 0)
{
return b;
}
if (b == 0)
{
return a;
}
if (!(a & 1) && !(b & 1))
{
return kgcd(a >> 1, b >> 1) << 1;
}
else if (!(b & 1))
{
return kgcd(a, b >> 1);
}
else if (!(a & 1))
{
return kgcd(a >> 1, b);
}
else
{
return kgcd(abs(a - b), min(a, b));
}
}
int main(int argc, const char * argv[])
{
int T;
cin >> T;
int res;
for (int i = 1; i <= T; i++)
{
cin >> n >> a >> b;
res = kgcd(a, b);
if ((n / res) & 1)
{
printf("Case #%d: Yuwgna\n", i);
}
else
{
printf("Case #%d: Iaka\n", i);
}
}
return 0;
}
Three:
// AC 模版通过
#include <iostream>
using namespace std;
int n, a, b;
/*
* 求x,y使得gcd(a, b) = a * x + b * y;
*/
int extgcd(int a, int b, int &x, int &y)
{
if (b == 0)
{
x = 1;
y = 0;
return a;
}
int d = extgcd(b, a % b, x, y);
int t = x;
x = y;
y = t - a / b * y;
return d;
}
int main(int argc, const char * argv[])
{
int T;
cin >> T;
int res, x, y;
for (int i = 1; i <= T; i++)
{
cin >> n >> a >> b;
res = extgcd(a, b, x, y);
if ((n / res) & 1)
{
printf("Case #%d: Yuwgna\n", i);
}
else
{
printf("Case #%d: Iaka\n", i);
}
}
return 0;
}
测试结果
三种模版测试均通过,不过第二种快速 GCD 非但不快,反而耗时更高,经过考虑,决定删除它。