Codeforces Round #323 (Div. 2): C. GCD Table(思维题)

版权声明:本文为博主原创文章,你们可以随便转载 https://blog.csdn.net/Jaihk662/article/details/83349940

题意:

给你一个长度为n的序列a[1]~a[n], 之后用这个序列生成一个n*n的矩阵,其中矩阵第i行第i列的值为a[i],第i行第j列(j!=i)的值为Gcd(a[i], a[j]),现在给你一个矩阵(里面元素被打乱),求复原这个序列(答案可能不唯一输出任意一种)

思路:

可以证明序列中元素顺序不影响答案,将所有矩阵元素从大到小塞入一个可重集合,之后按照以下操作即可:

  1. 取出当前最大元素x,x一定是原序列中的一个元素
  2. 暴力x与前面所有已经确定的序列元素的Gcd,将它们从可重集合中删除(注意矩阵因为对称,删除2次)

搞定

#include<stdio.h>
#include<string.h>
#include<algorithm>
#include<map>
#include<string>
#include<math.h>
#include<queue>
#include<set>
#include<stack>
#include<iostream>
using namespace std;
#define LL long long
#define mod 1000000007
multiset<int> st;
int ans[250005];
int Gcd(int x, int y)
{
	if(y==0)
		return x;
	return Gcd(y, x%y);
}
int main(void)
{
	int n, i, x, cnt;
	scanf("%d", &n);
	for(i=1;i<=n*n;i++)
	{
		scanf("%d", &x);
		st.insert(x);
	}
	cnt = 0;
	while(st.empty()==0)
	{
		ans[++cnt] = *(--st.end());
		st.erase(--st.end());
		for(i=cnt-1;i>=1;i--)
		{
			st.erase(st.lower_bound(Gcd(ans[i], ans[cnt])));
			st.erase(st.lower_bound(Gcd(ans[i], ans[cnt])));
		}
	}
	for(i=1;i<=cnt;i++)
		printf("%d ", ans[i]);
	puts("");
	return 0;
}

猜你喜欢

转载自blog.csdn.net/Jaihk662/article/details/83349940