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;
}

 

posted @ 2021-03-25 18:15  cono奇犽哒  阅读(54)  评论(0)    收藏  举报