2020 CCPC Wannafly Winter Camp Day1 H最大公约数

题目链接:

输入描述:
输入第一行是一个整数 T(1 ≤T ≤ 50)。
对于每组数据,输入一行两个整数 n,k(1≤k≤n≤500)。

输出描述:
对于每组数据,输出一行一个整数,表示答案。如果满足条件的 y 不存在,则输出 -1。

思路:看了别人博客后自己再想了下,首先题目意思为要验证gcd(k,y)与gcd(x,y)是否相等(假定k为A说的,x为B口中说的),因为A、B共同知晓的x范围限定在[1,n],那么A口中说的k也在[1,n](若k不在这个范围,肯定就是A说谎了),题意要找到一个可以判断真假的y,就是要找到一个y使得gcd(k,y)与gcd(xi,y)(1<=xi<=n&&xi!=k)都不相等,假定y<k时,1<=gcd(k,y)<=y,那么gcd(gcd(k,y),y)就会等于gcd(k,y),不成立,再讨论y>=k的情况,1<=gcd(k,y)<=k,那么gcd(gcd(k,y),y)就会等于gcd(k,y),当gcd(k,y)=k的时候,才成立。那么就是说y是k的倍数,但这只是必要条件,还需要排除在[1,n]区间中k的其他倍数的影响,例如当k=2,对于y=4时,gcd(6,4)也等于gcd(2,4)。怎么办呢,y就要等于k与[1,n]区间k的倍数除去k后都质因数分解后所有不同的质数的乘积相乘即可,这样可以保证求出来的y对于k的其他倍数的gcd不等于k,同时y又是满足题意的最小值。因为只是求所有不同质数,所以无需对所有k的倍数质因数分解,只要筛选出[1,n/k]区间的质数即可。最后结果可能是大整数,我就用java写了。

	import java.io.OutputStream;
	import java.math.*;
	import java.util.*;
    import java.io.IOException;
    import java.io.InputStream;
    import java.io.PrintWriter;
    import java.io.StreamTokenizer;
import java.math.BigInteger;

import javax.script.ScriptEngine;
import javax.script.ScriptEngineManager;
import javax.script.ScriptException;
import java.io.IOException;
    import java.io.BufferedReader;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.InputStreamReader;
    import java.io.InputStream;

    /**
     * Built using CHelper plug-in
     * Actual solution is at the top
     */
    public class Main {
    	static int primes[],m;
        public static void main(String[] args) throws IOException, ScriptException {
            InputStream inputStream = System.in;
            OutputStream outputStream = System.out;
            InputReader in = new InputReader(inputStream);
            PrintWriter out = new PrintWriter(outputStream);
            Task solver = new Task();
            init();
            int t=in.nextInt();
            while((t--)!=0)
            solver.solve(1, in, out);
            out.close();
        }

        private static void init() {
        	primes=new int[505];
        	m=0;
        	boolean v[]=new boolean[505];
        	for(int i=0;i<v.length;i++)
        		v[i]=true;
        	for(int i=2;i<=500;i++) {
        		if(!v[i])
        			continue;
        		primes[++m]=i;
        		for(int j=i;j<=500/i;j++)
        			v[i*j]=false;
        	}
		}

		static class Task {
            public void solve(int testNumber, InputReader in, PrintWriter out) throws IOException, ScriptException {
            	int n,k;
            	n=in.nextInt();
            	k=in.nextInt();
            	BigInteger ans=BigInteger.valueOf(k);
            	for(int i=1;i<=m&&primes[i]<=n/k;i++)
            		ans=ans.multiply(BigInteger.valueOf(primes[i]));
            	out.println(ans);
            }
        }
        static class InputReader{
            StreamTokenizer tokenizer;
            public InputReader(InputStream stream){
                tokenizer=new StreamTokenizer(new BufferedReader(new InputStreamReader(stream)));
                tokenizer.ordinaryChars(33,126);
                tokenizer.wordChars(33,126);
            }
            public String next() throws IOException {
                tokenizer.nextToken();
                return tokenizer.sval;
            }
            public int nextInt() throws IOException {
                return Integer.parseInt(next());
            }
            public long nextLong() throws IOException {
                return Long.parseLong(next());
            }
            public boolean hasNext() throws IOException {
                int res=tokenizer.nextToken();
                tokenizer.pushBack();
                return res!=tokenizer.TT_EOF;
            }
            
            public double nextDouble() throws NumberFormatException, IOException {
                return Double.parseDouble(next());
            }
            
            public BigInteger nextBigInteger() throws IOException {
                return new BigInteger(next());
            }
        }
    }    
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值