我随便猜了一个没什么根据的做法,但是过了,求问正确性
查看原帖
我随便猜了一个没什么根据的做法,但是过了,求问正确性
277792
Delov楼主2023/1/30 14:18

首先可以看出不互质的两数在序列中的相对位置不会改变,然后就想到在不互质的数之间建边,然后尝试去选数。

然后从这里就开始离谱了,我的想法是直接把图拆分成若干,于是就按权值从小到大考虑每个点,如果还没有被选到某条链上,就从它开始,贪心的走邻接的最小点dfs找出一条链,然后放到生成的序列最后,直到所有点都被选到。这样是Alice的操作,然后Bob的操作就一个一个数考虑,贪心的往前能换且换了字典序更大就换,类似冒泡的一个过程,我不知道有什么正确性,纯粹考场上骗分编出来的。

代码如下

#include <bits/stdc++.h>
typedef long long ll;typedef unsigned long long ull; typedef double db;typedef long double ldb;
#define fre(x) freopen(#x ".in","r",stdin),freopen(#x ".out","w",stdout)
#define Rep(i,a,b) for(int i=a;i<=b;++i) 
#define Dwn(i,a,b) for(int i=a;i>=b;--i)
#define pii pair<int,int>
#define mair make_pair
#define fir first
#define sec second
using namespace std;

const int maxn=2e3+10;

int n;int a[maxn];
vector<int>vec;

struct Graph{
	vector<int>E[maxn];
	void lqx(int u,int v){ E[u].emplace_back(v); }
	bool vis[maxn];
	void Dfs(int u){
		vis[u]=true;vec.emplace_back(a[u]);
		for(auto v : E[u])if(!vis[v])Dfs(v);
	}
}G;

void solve(){
	cin>>n;Rep(i,1,n)cin>>a[i];
	sort(a+1,a+n+1);
    Rep(i,1,n)Rep(j,1,n)if(i!=j && __gcd(a[i],a[j])!=1)G.lqx(i,j);
	vec.emplace_back(0);Rep(i,1,n)if(!G.vis[i])G.Dfs(i);
	Rep(i,1,n){
		int pos=0;
		Dwn(j,i-1,1){
			if(__gcd(vec[j],vec[i])!=1)break;
			if(vec[j]<vec[i])pos=j;
		}
		if(pos){
			int j=i;while(j>pos){ swap(vec[j],vec[j-1]);--j; }
		}
	}
	Rep(i,1,n)cout<<vec[i]<<" ";
}

int main (){ ios::sync_with_stdio(false),cin.tie(0),cout.tie(0);return solve(),0; }
2023/1/30 14:18
加载中...