题目描述
链接:ac.nowcoder.com/acm/contest…
来源:牛客网
小红希望你构造一个数组,满足以下三个条件:
- 数组的元素都是素数。
- 数组所有元素相乘恰好等于 。
- 数组任意相邻两个元素不等。
输入描述:
一个正整数x。
输出描述:
如果无解,直接输出 -1 即可。
如果有解,第一行输入一个正整数,代表数组的大小。第二行输入个正整数,代表数组的元素。
有多解时输出任意合法解都可以。
示例1:
输入:
30
输出:
3
2 5 3
示例2:
输入:
1000000007
输出:
1
1000000007
示例3:
输入:
4
输出:
-1
示例4:
输入:
900
输出:
6
2 3 5 2 3 5
示例5:
输入:
1200
输出:
7
2 3 2 5 2 5 2
示例6:
输入:
1800
输出:
7
2 3 5 2 3 5 2
示例7:
输入:
2000
输出:
7
2 5 2 5 2 5 2
Code
#include<bits/stdc++.h>
#define ll long long
using namespace std;
#define pll pair<long long,long long>
bool isprime1(ll n){ //判断是否是素数
if(n<2){
return false;
}
if(n==2||n==3){
return true;
}
if(n%6!=1&&n%6!=5){
return false;
}
for(ll i=5;i<=sqrt(n);i+=6){
if(n%i==0||n%(i+2)==0){
return false;
}
}
return true;
}
bool cmp(pll a,pll b){
return a.second>b.second;
}
int main(){
ll x;
cin>>x;
if(x==1){
cout<<-1<<endl;
return 0;
}
vector<ll> vec;
map<ll,ll> mp;
//素数筛,质因数分解
for(ll i=2;i<=sqrt(x);i++){
while(x%i==0){
x/=i;
mp[i]+=1;
}
}
if(x!=1){
mp[x]+=1;
}
ll maxx=0;
ll sum=0;
vector<pll> vec2;
for(auto v:mp){
maxx=max(maxx,v.second);
sum+=v.second;
vec2.push_back(v);
}
//当出现次数最多的质因数的次数大于(总次数+1)/2的时候,
//无法保证相邻的两个数都不相同
if(maxx>(sum+1)/2){
cout<<-1<<endl;
return 0;
}
//策略:
//首先按照出现次数由多到少排列到vector中(自定义排序函数cmp)
//第一阶段:从头选一个,从尾部选一个
//第二阶段,如果出现次数第一多的数的次数=出现次数第二多的数的次数,
//顺序输出剩下的数
//NB.需要特别注意一下x=1的情况,x的输入范围是x>=1
//循环必须写for(auto &x:vec2)才能修改值,否则只能读取值
sort(vec2.begin(),vec2.end(),cmp);
int f=1,model=1;
cout<<sum<<endl;
ll last=-1;
while(sum>0){
if(vec2.size()>=2 && vec2[0].second==vec2[1].second){
model&=0;
}
if(!model){
while(sum>0){
for(auto &v:vec2){
if(v.first==last){
last=-1;
continue;
}
if(v.second>0){
cout<<v.first<<" ";
v.second--;
sum--;
}
}
}
return 0;
}
else if(model&1){
if(f&1){
vec2[0].second--;
cout<<vec2[0].first<<" ";
last=vec2[0].first;
if(vec2[0].second==0){
vec2.erase(vec2.begin());
}
f&=0;
}
else{
vec2[vec2.size()-1].second--;
cout<<vec2[vec2.size()-1].first<<" ";
last=vec2[vec2.size()-1].first;
if(vec2[vec2.size()-1].second==0){
vec2.erase(vec2.end()-1);
}
f|=1;
}
}
sum--;
}cout<<endl;
}