思路解析:
当a数组中有1的时候,直接将该1分配给数组b,剩下的其他元素分配给数组c;
当数组中没有1的时候,需要将数组a中所有数字的质因数存下(可以存放在vector<int>v[N]中),然后将含有公共因子的数字分在一组。
几点注意:
1、注意ai的范围
2、将公共因子的数字分在一组需要循环多次
代码如下:
#include<bits/stdc++.h>
using namespace std;
#define int long long
using T = pair<int, int>;
//set<int>S;
//unordered_map<int, int>mp;
const int N = 1e6 + 1;
struct node {
int x;
bool ok;
node(int x1 = 0, bool ok1 = false) {
x = x1;
ok = ok1;
}
};
node b[N];
vector<int>v[N];
vector<int>save_tmp;
set<int>st;
bool isfriend(int x) {
int i;
for (i = 0; i < v[x].size(); ++i) {
if (st.count(v[x][i])) {
return true;
}
}
return false;
}
signed main()
{
ios::sync_with_stdio(false);
cin.tie(0); cout.tie(0);
int i, j;
int q; cin >> q;
while (q--) {
int n; cin >> n;
int cnt{ 1 };
int count_num1{};
for (i = 1; i <= n; ++i) {
b[i].ok = false;
b[i].x = 0;
}
for (i = 1; i <= n; ++i) {
cin >> b[i].x;
if (b[i].x == 1) {
++count_num1;
}
if (v[b[i].x].size())continue;
int num = b[i].x;
for (j = 2; j <= sqrt(num); ++j) {
if (num % j == 0) {
v[b[i].x].push_back(j);
}
while (num % j == 0)num /= j;
}
if (num > 1)v[b[i].x].push_back(num);
}
if (count_num1 >= 1) {
int flag = 1;
cout << 1 << " " << n - 1 << endl;
cout << 1 << endl;
for (i = 1; i <= n; ++i) {
if (b[i].x == 1 && flag) {
flag = 0;
}
else {
cout << b[i].x << " ";
}
}cout << endl;
}
else {
st.clear();
for (i = 0; i < v[b[1].x].size(); ++i)st.insert(v[b[1].x][i]);
b[1].ok = true;
int tmp = 0;
while (tmp != cnt) {
tmp = cnt;
for (i = 2; i <= n; ++i) {
if (b[i].ok == false) {
if (isfriend(b[i].x)) {
b[i].ok = true;
++cnt;
for (j = 0; j < v[b[i].x].size(); ++j)st.insert(v[b[i].x][j]);
}
}
}
}
if (cnt == n) {
cout << -1 << " " << -1 << endl;
}
else {
cout << cnt << " " << n - cnt << endl;
for (i = 1; i <= n; ++i) {
if (b[i].ok) {
cout << b[i].x << " ";
}
else {
save_tmp.push_back(b[i].x);
}
}cout << endl;
for (auto x : save_tmp) {
cout << x << " ";
}cout << endl;
}save_tmp.clear();
}
}
return 0;
}