The GCD table G of size n × n for an array of positive integers a of length n is defined by formula
Let us remind you that the greatest common divisor (GCD) of two positive integers x and y is the greatest integer that is divisor of both x and y, it is denoted as . For example, for array a = {4, 3, 6, 2} of length 4 the GCD table will look as follows:
Given all the numbers of the GCD table G, restore array a.
The first line contains number n (1 ≤ n ≤ 500) — the length of array a. The second line contains n2 space-separated numbers — the elements of the GCD table of G for array a.
All the numbers in the table are positive integers, not exceeding 109. Note that the elements are given in an arbitrary order. It is guaranteed that the set of the input data corresponds to some array a.
In the single line print n positive integers — the elements of array a. If there are multiple possible solutions, you are allowed to print any of them.
4 2 1 2 3 4 3 2 6 1 1 2 2 1 2 3 2
4 3 6 2
1 42
42
2 1 1 1 1
1 1
这题的思路就是,向这n^2中不断的找最大的数,然后与前面已经按照同样方法选出来的数求最大公约数,并在后面的数中抹去,一直循环到选出n个数为之。
这题刚开始用vector做的一直超时,其实是可以用multisets来做更简单,因为multisets自带排序功能,(你可以试着输出multisets中的元素)他是按照从小到大的自然顺序存放数据的。
具体这个multisets内部是怎么回事,这里就不多说,其实用的时候只需要知道他是基于红黑二叉树实现的排序,执行查找、插入、删除等操作的时间复杂度为O(logn)就可以了。
#include<iostream>
#include<cstdio>
#include<set> ///这是它的头文件
#include<algorithm>
using namespace std;
static int gcd(int x, int y) {return y==0?x:gcd(y,x%y);} ///求最大公约数
bool cmp(const int &x,const int &y){
return x>y ;
}
int main() {
int n ;
while(~scanf("%d",&n)){
multiset<int> q ;
q.clear() ;
int a ;
for(int i=0;i<n*n;i++){
scanf("%d",&a);
q.insert(a) ;
}
multiset<int>::iterator it; ///迭代器,取数必须用
int arry[5005];
int c = 0 ;
for(int i=0;i<n;i++){
it = q.end() ;
it-- ;
arry[c]= *it ;
q.erase(it) ;
c++;
for(int j =0 ;j<c-1;j++){
int com = gcd(arry[j],arry[c-1]) ;
it = q.lower_bound(com);
q.erase(it);
it = q.lower_bound(com);
q.erase(it);
}
}
for(int i=0;i<c-1;i++){
printf("%d ",arry[i]);
}printf("%d\n",arry[c-1]);
}
return 0;
}
下面也附上我超时的vector代码,毕竟也写了好久。
唯一的参考价值就是,包含了一些vector的部分用法。
#include<iostream>
#include<cstdio>
#include<vector>
#include<algorithm>
using namespace std;
static int gcd(int x, int y) {return y==0?x:gcd(y,x%y);}
bool cmp(const int &x,const int &y){
return x>y ;
}
int main() {
int n ;
while(~scanf("%d",&n)){
vector<int> q ;
q.clear() ;
int a ;
for(int i=0;i<n*n;i++){
scanf("%d",&a);
q.push_back(a) ;
}
//sort(q.begin(),q.end(),cmp);
sort(q.begin(),q.end());
// vector<int>::iterator it;
// for(it=q.begin();it!=q.end();it++){
// printf("%d\n",*it);
// }
int arry[5005];
int c = 0 ;
for(int i=0;i<n;i++){
arry[c]= q.back();
q.erase(q.end()-1) ;
c++;
for(int j =0 ;j<c-1;j++){
int com = gcd(arry[j],arry[c-1]) ;
int k = lower_bound(q.begin(),q.end(),com)-q.begin();
q.erase(q.begin()+k);
q.erase(q.begin()+k);
}
}
for(int i=0;i<c-1;i++){
printf("%d ",arry[i]);
}printf("%d\n",arry[c-1]);
}
}