题目链接
实现方法
本题分为两步:
- 质因数分解;
- 数字重排序(相同数字不连续)
质因数分解使用线性筛法,并在求质因数的过程中不断减小原数字。
数字重排序与重排字符串方法相同。
- 使用有序集合multiset存放各质因数及其出现次数;
- 判断是否存在可行解(最多的次数ma是否超过总次数sum的一半,奇数为ma>sum/2+1);
- 先轮流输出次数最多和次数第二多的数字,直到最多的次数与第二多的次数相等;
- 循环依次输出剩余的所有数字(需要判断第3步输出的最后一个数字和第4步输出的第一个数字是否相同,相同需要交换顺序);
代码
#include <bits/stdc++.h>
using namespace std;
//输入的正整数范围超过了int的最大值,需要用long long
#define int long long
signed main() {ios::sync_with_stdio(false);cin.tie(nullptr);cout.tie(nullptr);int n;//使用map记录各质因数与其出现的次数map<int,int>m;cin>>n;//1不是素数,需要特判if(n==1)return cout<<-1,0;for(int i=2;i*i<=n;i++){while(n%i==0){m[i]++;n/=i;}}if(n>1)m[n]++;//使用multiset对质因数和出现次数重排序,并记录出现最多的次数multiset<pair<int,int>>s;int sum=0,ma=0;for(auto j:m){sum+=j.second;ma=max(ma,j.second);s.insert({j.second,j.first});}//判断是否存在可行解if(2*ma-1>sum)return cout<<-1,0;cout<<sum<<endl;if(s.size()==1){cout<<(*s.begin()).second<<endl;return 0;}int x;//while(sum>0){auto temp=*s.rbegin();s.erase(temp);auto temp2=*s.rbegin();s.erase(temp2);if(temp.first!=temp2.first){cout<<temp.second<<" ";temp.first--;if(temp.first){cout<<temp2.second<<" ";x=temp2.second;temp2.first--;}else break;s.insert(temp);s.insert(temp2);}else{s.insert(temp);s.insert(temp2);break;}sum--;}vector<pair<int,int>>v;for(auto i:s){v.push_back(i);}while(1){int jud=0;for(int i=v.size()-1;i>=0;i--){if(v[i].first){cout<<v[i].second<<" ";v[i].first--;jud=1;}}if(!jud)break;}return 0;
}