题目地址:http://acm.zju.edu.cn/onlinejudge/showProblem.do?problemCode=2678
题解 : 1本题的答案就是gcd(m,n)
2解释是这样的,棋盘上的点是 (i,j) 0<=i<=m-1; 0<=j<=n-1; 从(a,b)走k步到达的点就是 ((a+k)%m, (b+k)%n) 现在的问题就是,至少需要多少个整数对
(a,b) 构成一个 点集,使得 对任意的i,j , 0<=i<=m-1; 0<=j<=n-1;在这个点集中一定存在一个 (a0,b0) ,和一个整数k 。
成立着 ((a0+k)%m, (b0+k)%n) ==(i,j)
这是同余方程组问题 , 数论中可以证明, 使得x==a (mod m),x==b (mod n) 有解的充要条件是(m,n) |(a-b)
那么再本题中就是要求 (m,n)| j-i - (b-a)
3 分充分性和必要性两方面说明 点集的元素恰好就是(m,n);
充分性:只需要(m,n)个点就行了。 取(m,n)个点 : (0,y) 0<=y<=(m.n)-1; 这样的点构成的“b-a” 可以遍历mod (m,n) 的完系 ,所以不管j-i 在mod (m,n)取什么值,我们都可以在完系中把它抓出来,这样就整除啦
必要性: 少于(m,n)个元素是不行的: 一旦点的数量少于(m,n)那么“b-a”的值只会更少(因为可能还会重复),也就是说b-a 是取不了mod (m,n)的完系的。
显然j-i 是可以遍历的(不妨设m<=n, 令i=0,j运动就可以了 ) ,这与不管怎么取(i,j) 都有b-a 让他们满足同余关系矛盾了。
综上所述这样的最小点集元素个数就是(m,n)
import java.math.*; import java.util.*; import java.io.*; public class Main { public static void main(String[] args) throws Exception { Scanner cin=new Scanner(System.in); boolean first=true; while(cin.hasNext()) { if(first==false) System.out.println(); if(first==true) first=false; BigInteger m=cin.nextBigInteger(); BigInteger n=cin.nextBigInteger(); System.out.println(m.gcd(n)); } } }