P1414 又是毕业季II(约数统计,好题!)
彩排了一次,老师不太满意。当然啦,取每位同学的号数来找最大公约数显然不太合理。于是老师给每位同学评了一个能力值。于是现在问题变为,从n个学生中挑出k个人使得他们的默契程度(即能力值的最大公约数)最大。但因为节目太多了,而且每个节目需要的人数又不知道。老师想要知道所有情况下能达到的最大默契程度是多少。这下子更麻烦了,还是交给你吧~
PS:一个数的最大公约数即本身。
题意:要找从n个数中分别选出1-n个数,分别求出选出的数的值的最大公约数的最大值
思路:对每个数的约数个数进行统计,然后从大到小选择满足条件的约数,如果满足条件,则一定是选取该个数下的最大值
#include<bits/stdc++.h> using namespace std; typedef long long ll; const int maxn = 10005; int a[maxn]; int f[1000005]; int main() { //freopen("test.txt", "r", stdin); int n; scanf("%d", &n); int e = 0; for (int i = 1; i <= n; i++)scanf("%d", &a[i]); for (int i = 1; i <= n; i++) { e = max(e, a[i]); int t = sqrt(a[i]);//统计所有数约数的频数 for (int j = 1; j <= t; j++) { if (a[i] % j == 0) { f[j]++; if (j * j != a[i])f[a[i] / j]++; } } } int x = e;//从最大的可能约数开始判断 for (int i = 1; i <= n; i++) { while (f[x] <i)x--;//不满足就一直减,最终1肯定是满足的@_@ printf("%d\n", x); } return 0; }