【Codeforces Round 323 (Div 2)C】【观察找规律 STL map】GCD Table 从GCD矩阵中找出所有原始元素

C. GCD Table
time limit per test
2 seconds
memory limit per test
256 megabytes
input
standard input
output
standard output

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 xand 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.

Input

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.

Output

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.

Sample test(s)
input
4
2 1 2 3 4 3 2 6 1 1 2 2 1 2 3 2
output
4 3 6 2
input
1
42
output
42 
input
2
1 1 1 1
output
1 1 


#include<stdio.h>
#include<string.h>
#include<ctype.h>
#include<math.h>
#include<iostream>
#include<string>
#include<set>
#include<map>
#include<vector>
#include<queue>
#include<bitset>
#include<algorithm>
#include<time.h>
using namespace std;
void fre(){freopen("c://test//input.in","r",stdin);freopen("c://test//output.out","w",stdout);}
#define MS(x,y) memset(x,y,sizeof(x))
#define MC(x,y) memcpy(x,y,sizeof(x))
#define MP(x,y) make_pair(x,y)
#define ls o<<1
#define rs o<<1|1
typedef long long LL;
typedef unsigned long long UL;
typedef unsigned int UI;
template <class T1,class T2>inline void gmax(T1 &a,T2 b){if(b>a)a=b;}
template <class T1,class T2>inline void gmin(T1 &a,T2 b){if(b<a)a=b;}
const int N=505,M=0,Z=1e9+7,ms63=1061109567;
int casenum,casei;
int a[N][N];
int b[N*N];
int n,nn;
map<int,int>mop;
map<int,int>::iterator it;
int gcd(int x,int y)
{
	return y==0?x:gcd(y,x%y);
}
int main()
{
	while(~scanf("%d",&n))
	{
		mop.clear();
		for(int i=n*n;i;--i)
		{
			scanf("%d",&b[i]);
			++mop[b[i]];
		}
		int p=0;
		map<int,int>::iterator tmp;
		for(it=mop.begin();it!=mop.end();it++)if(it->second&1)
		{
			++p;a[p][p]=it->first;--it->second;
			for(int i=1;i<p;i++)
			{
				int x=gcd(a[i][i],a[p][p]);
				a[i][p]=a[p][i]=x;
				mop[x]-=2;
			}
		}
		while(p<n)
		{
			while(1)
			{
				it=--mop.end();
				if(it->second==0)mop.erase(it);
				else break;
			}
			int x=it->first;
			++p;a[p][p]=x;--mop[x];
			for(int i=1;i<p;i++)
			{
				int x=gcd(a[i][i],a[p][p]);
				a[i][p]=a[p][i]=x;
				mop[x]-=2;
			}
		}
		for(int i=1;i<=n;i++)printf("%d ",a[i][i]);
		puts("");
	}
	return 0;
}
/*
【trick&&吐槽】
做题没思路,从样例下手。

【题意】
给你n([1,500])个数a[],b[i][j]表示gcd(a[i],a[j])
b[][]有n*n个数,我们把它打乱顺序,全部告诉你。
让你输出所有的a[]。

【类型】
贪心 构造

【分析】
这题很有趣。
一开始想很难想,完全不知道思考的方向。
这时候我们要怎么办?没错!观察样例!
我们发现,这个矩阵肯定是关于主对角线对称的。
于是我们先找到出现次数为奇数的数,这些数一定是位于主对角线上的,同时对应着一个a[]。
然后我们同时生成所有的gcd。
然而这样并不一定能把这个矩阵完全还原。
剩下的数的出现次数都可能为偶数。
这时我们发现,数值最大的数(还没被取),肯定在矩阵的主对角线。于是就放上去。
重复这个操作,就可以AC这道题啦!

【时间复杂度&&优化】
O(n^2logn)

【数据】
4
4 4 4 4 2 2 2 2
2 2 2 2 2 2 2 2

*/


  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值