洛谷 P4571 [JSOI2009]瓶子和燃料

Description

洛谷传送门

Solution

一道裴蜀定理应用的题目。

裴蜀定理: 一定存在一组整数解使得 \(ax + by = gcd(a, b)\) 成立。

这里不再证明了,感兴趣的同学可以自行百度。

再来看这道题,假设只有两个瓶子,里面有燃料,可以来回倒。

那么不就是 \(ax + by\) 的形式吗,那么最大的值就为 \(gcd(a, b)\)

此时,原题就变成了给定 \(n\) 个数,从里面选出 \(k\) 个数,使得这 \(k\) 个数的 \(gcd\) 最大。

Code

#include <iostream>
#include <cstdio>
#include <algorithm>
#include <cstring>
#include <map>

using namespace std;

const int N = 1e5 + 10;
int n, k, cnt;
int p[N];//记录这 n 个数中有哪些个不同的因数,一共有 cnt 个。
map <int, int> mp;//mp[x]: 表示含有因数 x 的数有多少个。

int main(){
	scanf("%d%d", &n, &k);
	for(int i = 1; i <= n; i++){
		int x;
		scanf("%d", &x);
		for(int j = 1; j * j <= x; j++){
			if(x % j != 0) continue;
			if(!mp[j]) p[++cnt] = j;//把因数存下来
			mp[j]++;//包含因数 j 的数个数++
			if(!mp[x / j]) p[++cnt] = x / j;//处理 x / j
			if(j * j != x) mp[x / j]++;
		}
	}
	int ans = 0;
	for(int i = 1; i <= cnt; i++)
		if(mp[p[i]] >= k)//包含因数 p[i] 的数个数 >= k 时,统计最大值
			ans = max(ans, p[i]);
	printf("%d\n", ans);
	return 0;
}

End

posted @ 2021-10-09 22:12  xixike  阅读(30)  评论(0编辑  收藏  举报