2020 CCPC Wannafly Winter Camp Day1 Div.1&2(H 最大公约数)(找规律+大整数乘法)

2020 CCPC Wannafly Winter Camp Day1 Div.1&2(H 最大公约数)(找规律+大整数乘法)

时间限制:C/C++ 2秒,其他语言4秒
空间限制:C/C++ 262144K,其他语言524288K
64bit IO Format: %lld

题目描述

有三个人, A , B , C {A,B,C} ,其中 A {A} B {B} 共享了一个神秘的数字 k {k} ,已知 1 k n 1 \leq k \leq n
现在 A {A} C {C} 说:“ k {k} 的值等于 x {x} ”。
C {C} 不太信任 A {A} ,于是想向 B {B} 确认一下 k {k} 是否真的等于 x {x} B {B} 虽然不想直接把 k {k} 的值告诉 C {C} ,但是 B {B} 允许 C {C} 给出一个正整数 y {y} (注意 y {y} 可以大于 n {n} ),然后 B {B} 会回答 gcd ( k , y ) \gcd(k,y)
现在给出 k , n {k,n} ,你需要帮助 C {C} 决定这样的 y {y} 的取值,使得 C {C} 一定可以通过 B B 的回答来判断 A A 有没有撒谎。如果这样的 y y 有多个,你需要输出最小的那个。

输入描述:

输入第一行是一个整数 T ( 1 T 50 ) T(1 \leq T \leq 50)
对于每组数据,输入一行两个整数 n , k ( 1 k n 500 ) n,k(1 \leq k \leq n \leq 500)

输出描述:

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

示例1

输入

3
10 1
10 4
10 7

输出

210
8
7

备注:

输入的 k k 指的是 A A 告诉 C C 的值,只需要检验它对不对就行

题解

题目中的 k k 是游戏开始前设定的未知数,而 x x 是游戏时 A A 给出的固定值,那么 k k 是变量。而备注中说

输入的 k k 指的是 A A 告诉 C C 的值,只需要检验它对不对就行

说明输入的是 n n x x

我们假设一个数字 a n s = ( n × x ) ans = (所有小于等于n的素数的乘积 × x)

那么 g c d ( x , a n s ) gcd(x,ans) g c d ( k , a n s ) gcd(k,ans) 是否相等即代表 k k x x 是否相等。


证明:

  • 如果 k k 不是 x x 的倍数那么 g c d ( k , a n s ) gcd(k,ans) 一定不能整除 x x (即 x % g c d ( k , a n s ) 0 x\%gcd(k,ans)≠0 ),而 a n s ans x x 的倍数,所以 g c d ( x , a n s ) = x gcd(x,ans)=x ,其一定能整除 x x (即 x % g c d ( x , a n s ) = 0 x\%gcd(x,ans)=0 ),所以 g c d ( k , a n s ) g c d ( x , a n s ) gcd(k,ans)≠gcd(x,ans)
  • 如果 k k x x 的倍数且 k k 不等于 x x ,且 a n s = ( n × x ) ans = (所有小于等于n的素数的乘积 × x) ,那么 g c d ( k , a n s ) = z × x ( z 1 ) gcd(k,ans)=z×x(z是大于1的整数) g c d ( x , a n s ) = x gcd(x,ans)=x 所以 g c d ( k , a n s ) g c d ( x , a n s ) gcd(k,ans)≠gcd(x,ans)
  • 如果 k k 等于 x x ,则 g c d ( k , a n s ) = g c d ( x , a n s ) gcd(k,ans)=gcd(x,ans)

证毕。


综上所述,这道题的答案就是 a n s ans

a n s = ( n × x ) ans = (所有小于等于n的素数的乘积 × x)

注意题目要用大整数乘法。

代码

#include<bits/stdc++.h>
using namespace std;

int p[505], n, m, i, j, t, k, l, a[505];
bool vis[505];

void mul(int x) {
	int i; // 定义临时变量 !
	for (i = 0; i < l; i++) a[i] *= x;
	for (i = 0; i < l; i++) {
		a[i + 1] += a[i] / 10;
		a[i] %= 10;
	}
	for (; a[l]; l++) {
		a[l + 1] = a[l] / 10;
		a[l] %= 10;
	}
}

int main() {
	freopen("in.txt", "r", stdin);
	n = 500;
	for (i = 2; i <= n; i++) {	//线筛
		if (!vis[i]) p[m++] = i;
		for (j = 0; j < m && i*p[j] <= n; j++) {
			vis[i*p[j]] = 1;
			if (i%p[j] == 0) break;
		}
	}
	scanf("%d", &t);
	while (t--) {
		scanf("%d%d", &n, &k);
		memset(a, 0, sizeof(a));
		a[0] = l = 1;
		for (i = 0; i < m && k*p[i] <= n; i++) mul(p[i]);
		mul(k);
		for (i = l - 1; ~i; i--) printf("%d", a[i]);
		puts("");
	}
}
发布了165 篇原创文章 · 获赞 54 · 访问量 3万+

猜你喜欢

转载自blog.csdn.net/weixin_42856843/article/details/104092042