第3题 修塔 查看测评数据信息
有编号1~n 的n个塔,除了两个塔a和b 是好的不用修以外,其他都需要重修。
james和jordan展开修塔比赛,规则是轮流修,每次可以修第j+k或j-k号塔,其中j和k是已经修好的任意两个塔,
如果不能修塔,就输了。给出n,a,b,从 james开始,问最后谁赢了。
输入格式
第一行,一个整数T, 1<=T<=10000,表示有T组测试数据。
接下来T行,每行3个整数: n,a,b。2<a,b,n≤200000。a!=b。
输出格式
共T行,每行一个字符串。
输入/输出例子1
输入:
1
5 2 3
输出:
james
样例解释
无
问题分析:
分析一下,第一轮可能是a-b,a+b,b-a,b+a
第二轮可能是a-2b,2a-b,2a+b,2b+a,b-2a,2b-a,等等等等
我们发现这些数都是由 xa+yb组合而来的,很像线性组合,其中x,y为整数
考虑几个线性组合相加,ax1+by1+ax2+by2=a(x1+x2)+b(y2+y1),2个整数相加的结果也是整数
有可能得出7a+3b吗?可以的,比如a+a+...+a+b+b+b,7a-3b也都可以取到
但是1<= 7a+3b <=n 才可以取到。我们举例,4x+6y,结果一定是gcd(4,6)的倍数
一共有n/gcd(a,b)个塔,根据上面举例推广而来,这样就只要判断塔的奇偶性即可求出答案
如果能算出所有能修的塔的数量P,然后判断P的奇偶,若P为奇数,就是先手 james赢,P为偶数就是后手jordan赢。
可以试试暴力计算P。先预处理出a、b、a+b、a-b、2a+b、2a-b等,即可以修的塔的编号a和b的线性组合,即ax+by,再判断这些塔号是否合法,判断时需要枚举工和y,复杂度为O(n^2)。(也可以用宽搜)
下面用数论的办法直接得到P。根据裴蜀定理,ax + by是gcd(a,b)的整数倍,也就是说,P是所有gcd(a,b)的倍数的个数,则P = n/gcd(a,b)。
以下是参考程序:
#include <bits/stdc++.h> using namespace std; int t, n, a, b; int gcd(int a, int b) { if (b==0) return a; return gcd(b, a%b); } int main() { scanf("%d", &t); while (t--) { scanf("%d%d%d", &n, &a, &b); if ((n/gcd(a, b))%2==0) printf("jordan\n"); else printf("james\n"); } return 0; }
标签:gcd,int,james,整数,2a,修塔,裴蜀 From: https://www.cnblogs.com/didiao233/p/18004352