根据数表形成的规则,可以很轻松的发现,当前数表中最大的两个数一定是原数列中的数,求出它们的gcd,那么当前数表中一定有两个gcd是他们形成的,将其去除。
用什么容器维护都可以,我用的multiset
细节参见代码:
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int INF = 1000000000;
const int maxn = 500 + 5;
int n,m,T,cnt;
ll a, ans[maxn];
ll gcd(ll a, ll b) {
return b == 0 ? a : gcd(b, a%b);
}
multiset<ll> g;
int main() {
while(~scanf("%d",&n)) {
g.clear();
for(int i=0;i<n*n;i++) {
scanf("%I64d",&a);
g.insert(a);
}
cnt = 0;
set<ll> :: iterator it;
while(!g.empty()) {
it = g.end(); --it;
ll v = *it;
g.erase(it);
for(int i=0;i<cnt;i++) {
ll u = gcd(ans[i], v);
it = g.lower_bound(u);
g.erase(it);
it = g.lower_bound(u);
g.erase(it);
}ans[cnt++] = v;
}
for(int i=0;i<cnt;i++) {
if(i == 0) printf("%I64d",ans[i]);
else printf(" %I64d",ans[i]);
}
printf("\n");
}
return 0;
}