2020 CCPC Wannafly Winter Camp Day1 Div.1&2(H 最大公约数)(找规律+大整数乘法)
时间限制:C/C++ 2秒,其他语言4秒
空间限制:C/C++ 262144K,其他语言524288K
64bit IO Format: %lld
题目描述
有三个人,
,其中
和
共享了一个神秘的数字
,已知
。
现在
和
说:“
的值等于
”。
不太信任
,于是想向
确认一下
是否真的等于
。
虽然不想直接把
的值告诉
,但是
允许
给出一个正整数
(注意
可以大于
),然后
会回答
。
现在给出
,你需要帮助
决定这样的
的取值,使得
一定可以通过
的回答来判断
有没有撒谎。如果这样的
有多个,你需要输出最小的那个。
输入描述:
输入第一行是一个整数
。
对于每组数据,输入一行两个整数
。
输出描述:
对于每组数据,输出一行一个整数,表示答案。如果满足条件的 不存在,则输出 。
示例1
输入
3
10 1
10 4
10 7
输出
210
8
7
备注:
输入的 指的是 告诉 的值,只需要检验它对不对就行
题解
题目中的 是游戏开始前设定的未知数,而 是游戏时 给出的固定值,那么 是变量。而备注中说
输入的 指的是 告诉 的值,只需要检验它对不对就行
说明输入的是 和
我们假设一个数字
那么 和 是否相等即代表 和 是否相等。
证明:
- 如果 不是 的倍数那么 一定不能整除 (即 ),而 是 的倍数,所以 ,其一定能整除 (即 ),所以 。
- 如果 是 的倍数且 不等于 ,且 ,那么 且 所以 。
- 如果 等于 ,则 。
证毕。
综上所述,这道题的答案就是 。
。
注意题目要用大整数乘法。
代码
#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("");
}
}