(1 )题意:
给定一个整数n,, 构造一个数组,要求数组的每个数都是素数,并且相邻的数都不同,所有数相乘以后是n,如果存在则先输出数组的长度并且输出数组的元素,否则输出-1。
(2) 题解:
我们先挖掘一下这个数组的性质,我们可以发现必须对n进行质因数分解,分解以后再进行考虑怎么样让相邻的质因数不同,我们先考虑筛质数,可以范围太大,没办法直接筛,考虑试除法,时间复杂度是,显然可以单独每个样例进行试除法质因数分解。代码如下:
cin >> n; queue<int> q; vector<int> us; q.push(n); while(q.size()) { auto t = q.front(); q.pop(); if(t <= 1) continue; int mx = -1; for(int i = 2; i <= t / i; i ++ ) if(t % i == 0) mx = max(mx, i); if(mx == -1) us.push_back(t); else { if(mx > 1) q.push(mx); if(t / mx > 1) q.push(t / mx); } }
我们现在得到了数组的元素,现在开始构造符合相邻之间不相等的数组。假设有数字集合
>= 1,我们可以每次取min(cnt),得到一个序列按顺序将元素排好,这样只会剩下最多一种元素再将其插入到符合条件的间隔中,举个例子,有集合{2, 3, 5},cnt[2] = 3, cnt[3] = 2, cnt[5] = 1, 那我们先知道最小的cnt[5] = 1, 可以凑出: {2, 3, 5}, 此时集合变成: {2, 3}, cnt[2] = 2, cnt[3] = 1, 我们知道最小的是cnt[3] = 1, 可以凑出:{2, 3, 5, 2, 3},此时集合只剩{2},cnt[2] = 1, 我们找到交替的位置插入得到{2, 3, 2, 5, 2, 3},这样能使得每次元素的利用是最大的。并且一定是要按照数字个数的顺序去排好,因为这样可以给数字大的数留足够多的间隔。
代码:
#include <bits/stdc++.h>
#define int long long
#define ff first
#define ss second
#define pb push_back
using namespace std;
using PII = pair<int,int>;
constexpr int N = 2e6 + 10;
constexpr int inf = 0x3f3f3f3f;
int n, m;
map<int, int> mp;
vector<int> ans(N, 0);
bool cmp(int x, int y) {
return mp[x] > mp[y];
}
void solve() {
cin >> n;
if(n == 1) {
cout << -1 << endl;
return;
}
queue<int> q;
vector<int> us;
q.push(n);
while(q.size()) {
auto t = q.front();
q.pop();
if(t <= 1) continue;
int mx = -1;
for(int i = 2; i <= t / i; i ++ )
if(t % i == 0) mx = max(mx, i);
if(mx == -1) us.push_back(t);
else {
if(mx > 1) q.push(mx);
if(t / mx > 1) q.push(t / mx);
}
}
// for(auto t : us) cout<<t<<endl;
if(us.size() == 1) {
cout << 1 << endl << us[0] << endl;
return;
}
// return;
vector<int> h;
for(auto t : us) mp[t] ++;
for(auto t : mp) h.push_back(t.ff);
sort(h.begin(), h.end(), cmp);
int l = h.size() - 1;
// cout << l << endl;
int idx = 0;
while(l > 0 && mp[h[l]] > 0) {
for(int o = 0; o < mp[h[l]]; o ++ )
for(int i = 0; i < h.size(); i ++ )
if(mp[h[i]] >= mp[h[l]]) {
ans[idx] = h[i];
idx += 2;
}
else break;
int u = mp[h[l]];
for(int i = 0; i < h.size(); i ++ )
if(mp[h[i]] >= u) mp[h[i]] -= u;
while(l >= 0 && mp[h[l]] <= 0) l --;
}
if(mp[h[l]]) {
for(int i = 1; i < idx; i += 2)
if(ans[i - 1] != h[l] && ans[i + 1] != h[l] && mp[h[l]])
mp[h[l]] --, ans[i] = h[l];
}
if(mp[h[l]]) cout<<-1<<endl;
else {
int t = 0;
for(int i = 0; i < N; i ++ )
if(ans[i] != 0) ++ t;
cout << t << endl;
for(int i = 0; i < N; i ++ )
if(ans[i] != 0) cout << ans[i] << ' ';
cout << endl;
}
}
signed main() {
int ts = 1;
// cin >> ts;
while(ts --) solve();
return 0;
}