HDU 5207 Greatest Greatest Common Divisor(暴力)

和很多题目的思路是一样的, 因为如果直接二重循环枚举的话时间复杂度是承受不了的, 所以我们不妨换个思路, 先预处理出来没个数出现的次数, 然后从1枚举到最大值i, 对于每个i , 我们找它的倍数, 那么它的倍数肯定以它为最大公约数(因为是从大到小枚举的), 如果超过两个, 则存在以i为最大公约数的两个数, 那么这个i也就是最大的。

细节参见代码:

#include<cstdio>
#include<cstring>
#include<algorithm>
#include<iostream>
#include<string>
#include<vector>
#include<stack>
#include<bitset>
#include<cstdlib>
#include<cmath>
#include<set>
#include<list>
#include<deque>
#include<map>
#include<queue>
#define Max(a,b) ((a)>(b)?(a):(b))
#define Min(a,b) ((a)<(b)?(a):(b))
using namespace std;
typedef long long ll;
const double PI = acos(-1.0);
const double eps = 1e-6;
const int INF = 1000000000;
const int maxn = 100000+7;
int T,n,m,kase = 0,a[maxn], vis[maxn];
int main() {
    scanf("%d",&T);
    while(T--) {
        scanf("%d",&n);
        int maxv = 0;
        for(int i=0;i<n;i++) {
            scanf("%d",&a[i]);
            maxv = max(a[i], maxv);
        }
        int ans = 0;
        memset(vis, 0, (maxv+1)*sizeof(int));
        for(int i=0;i<n;i++) vis[a[i]]++;
        for(int i=maxv;i>=1;i--) {
            int cur = 0;
            for(int j=i;j<=maxv;j+=i) {
                cur += vis[j];
                if(cur > 1) break;
            }
            if(cur > 1) { printf("Case #%d: %d\n",++kase, ans);  break; }
        }
    }
    return 0;
}





你可能感兴趣的:(HDU,暴力)