反正比赛的时候没想到怎么做,主要应该还是智商问题,比赛的时候胡思乱想很久,没想到怎么做:
其实也很简单:
题意:
由n个数,可以构成一个n*n的gcd矩阵 (每两个数之间)
现在给你n*n个数(任意序),求出 矩阵对应的 n个数(任一合法答案)
可知: 最大的数必然是要求的数。。。(不可能存在两个数的公约数是他)(如果最大的数有多个,那么MAX与MAX的公约数是MAX这种情况不影响)
所以我们每次只要把当前剩下最大的数选了放进数组,然后与之前已选到的数求一遍gcd,把求到的gcd数在原序列中删掉,这样一直选,可以确保答案是正确的
每两个要求的数,必会在原矩阵 产生2个一样的gcd、所以求到一个gcd数,要删掉2次。
#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <map>
#include <set>
#include<cmath>
#include<climits>
#include<vector>
#include<cfloat>
#include<queue>
#include<cctype>
#include<cstdlib>
#define LL long long
using namespace std;
const int N=1e3;
int n,res[N];
void work()
{
scanf("%d",&n);
map<int,int> Hash;
for(int i=0;i<n*n;i++)
{
int x;
scanf("%d",&x);
++Hash[x];
}
for(int i=0;i<n;i++)
{
res[i]=(--Hash.end())->first;
if(!--Hash[res[i]])
Hash.erase(res[i]);
for(int j=0;j<i;j++)
{
int x=__gcd(res[i],res[j]);
if(!--Hash[x])
Hash.erase(x);
if(!--Hash[x])
Hash.erase(x);
}
cout<<res[i]<<endl;
}
}
int main()
{
work();
return 0;
}