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
judge:點我跳轉

題目描述

有三個人,A,B,C{A,B,C} ,其中 A{A}B{B} 共享了一個神祕的數字 k{k},已知 1kn1 \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} 一定可以通過 BB 的回答來判斷 AA 有沒有撒謊。如果這樣的 yy 有多個,你需要輸出最小的那個。

輸入描述:

輸入第一行是一個整數 T(1T50)T(1 \leq T \leq 50)
對於每組數據,輸入一行兩個整數 n,k(1kn500)n,k(1 \leq k \leq n \leq 500)

輸出描述:

對於每組數據,輸出一行一個整數,表示答案。如果滿足條件的 yy 不存在,則輸出 1-1

示例1

輸入

3
10 1
10 4
10 7

輸出

210
8
7

備註:

輸入的 kk 指的是 AA 告訴 CC 的值,只需要檢驗它對不對就行

題解

題目中的 kk 是遊戲開始前設定的未知數,而 xx 是遊戲時 AA 給出的固定值,那麼 kk 是變量。而備註中說

輸入的 kk 指的是 AA 告訴 CC 的值,只需要檢驗它對不對就行

說明輸入的是 nnxx

我們假設一個數字 ans=(n×x)ans = (所有小於等於n的素數的乘積 × x)

那麼 gcd(x,ans)gcd(x,ans)gcd(k,ans)gcd(k,ans) 是否相等即代表 kkxx 是否相等。


證明:

  • 如果 kk 不是 xx 的倍數那麼 gcd(k,ans)gcd(k,ans) 一定不能整除 xx(即 x%gcd(k,ans)0x\%gcd(k,ans)≠0 ),而 ansansxx 的倍數,所以 gcd(x,ans)=xgcd(x,ans)=x ,其一定能整除 xx (即 x%gcd(x,ans)=0x\%gcd(x,ans)=0 ),所以 gcd(k,ans)gcd(x,ans)gcd(k,ans)≠gcd(x,ans)
  • 如果 kkxx 的倍數且 kk 不等於 xx ,且 ans=(n×x)ans = (所有小於等於n的素數的乘積 × x) ,那麼 gcd(k,ans)=z×x(z1)gcd(k,ans)=z×x(z是大於1的整數)gcd(x,ans)=xgcd(x,ans)=x 所以 gcd(k,ans)gcd(x,ans)gcd(k,ans)≠gcd(x,ans)
  • 如果 kk 等於 xx ,則 gcd(k,ans)=gcd(x,ans)gcd(k,ans)=gcd(x,ans)

證畢。


綜上所述,這道題的答案就是 ansans

ans=(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("");
	}
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章