思路:
首先这个题我们可能想到的就是任意两个数的 gcd ,
但是这样还不够,可能会有 已经得出的gcd 跟其他的数产生新的 gcd,所以,这个题的答案就是 n 个数所有子集的gcd
(上面这些想了好久没能证明== 感谢Q巨 tls 九哥 等大神 瞬间给出我没想出来的反例,当头一棒,叫我清醒,对数学更加喜欢)
#include<iostream>
#include<algorithm>
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<string>
#include<cmath>
#include<set>
#include<queue>
#include<stack>
#include<map>
#define PI acos(-1.0)
#define in freopen("in.txt", "r", stdin)
#define out freopen("out.txt", "w", stdout)
using namespace std;
typedef long long ll;
typedef unsigned long long ull;
const int maxn = 1e3 + 7, maxd = 555, mod = 1e9 + 7;
const int INF = 0x7f7f7f7f;
int gcd(int a, int b) {
return b == 0 ? a : gcd(b, a%b);
}
int T, n;
bool cnt[maxn];
int a[maxd];
int main() {
scanf("%d", &T);
while(T--) {
scanf("%d", &n);
memset(cnt, 0, sizeof cnt);
for(int i = 1; i <= n; ++i) {
scanf("%d", &a[i]);
}
int i;
for(i = 1; i <= n; ++i) {
for(int j = i+1; j <= n; ++j) {
cnt[gcd(a[i],a[j])] = true;
}
}
int f = 1, num = 1;
while(f && num < n-2) {
f = 0;
num++;
for(int i = 1; i <= 1000; ++i) {
if(cnt[i]) {
for(int j = 1; j <= n; ++j) {
int t = gcd(i, a[j]);
if(cnt[t] == 0) {
f = 1;
cnt[t] = true;
}
}
}
}
}
for(i = 1; i <= 1000; ++i)
if(cnt[i]) { printf("%d", i); ++i; break; }
for( ; i <= 1000; ++i)
if(cnt[i]) printf(" %d", i);
puts("");
}
return 0;
}