和很多题目的思路是一样的, 因为如果直接二重循环枚举的话时间复杂度是承受不了的, 所以我们不妨换个思路, 先预处理出来没个数出现的次数, 然后从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;
}