[CF1419E] Decryption

Description

给定一个正整数 n,将它的所有大于一的因数按照任意顺序排列在一个环上,你每次可以选择圈上相邻的两个数,在它们中间插入他们的最小公倍数,使得最后的环上不存在两个相邻且互质的数。你需要找到一个需要进行操作次数最少的排列。

Solution

一种确定的思路是,枚举最小质因子,用掉所有它的倍数,并注意把下一个质因子留一个数用来作为从这个最小质因子到下一个最小质因子的过渡。这种方法是容易证明的。

另一种思路是,从最小数开始,每次选择一个与上一个输出的数不互质的未被使用的最小的数输出。(非常优美但是不会证明)

#include <bits/stdc++.h>
using namespace std;

#define int long long 
const int N = 1000005;

signed main()
{
    int t;
    cin>>t;
    while(t--)
    {
        int n;
        cin>>n;
        vector <int> fac;
        for(int i=2;i*i<=n;i++)
        {
            if(n%i==0)
            {
                fac.push_back(i);
                if(i*i!=n) fac.push_back(n/i);
            }
        }
        fac.push_back(n);
        vector <int> ans;
        set <int> s;
        for(int i:fac) s.insert(i);
        int last=*s.begin();
        s.erase(s.begin());
        cout<<last<<" ";
        int first=last;
        while(s.size())
        {
            auto it=s.begin();
            while(__gcd(*it,last)<=1 && it!=(--s.end())) ++it;
            int now=*it;
            s.erase(it);
            cout<<now<<" ";
            last=now;
        }
        cout<<endl;
        if(__gcd(first,last)==1) puts("1");
        else puts("0");
    }
    return 0;
}
原文地址:https://www.cnblogs.com/mollnn/p/13885981.html