版权声明:本文为博主原创文章,你们可以随便转载 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]),现在给你一个矩阵(里面元素被打乱),求复原这个序列(答案可能不唯一输出任意一种)
思路:
可以证明序列中元素顺序不影响答案,将所有矩阵元素从大到小塞入一个可重集合,之后按照以下操作即可:
- 取出当前最大元素x,x一定是原序列中的一个元素
- 暴力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;
}