题目链接:https://ac.nowcoder.com/acm/contest/5669/H
题意:
- 把1~N的数分成尽量多的组(俩个为1组),使得每组gcd大于1.
- 输出任意一种方案
题解:
- p * 2 > n 的 p 必然不能匹配,将他们除去
- 倒序枚举所有质因子p,考虑所有是 p 的倍数、且未被匹配的书,任意将他们匹配,如果个数是奇数就留下p * 2
- 最后把偶数随意匹配一下
1 #include<iostream> 2 #include<cstring> 3 #include<algorithm> 4 #include<cmath> 5 #include<stdlib.h> 6 #include<vector> 7 #include<algorithm> 8 #include<stack> 9 using namespace std; 10 const int N=2e5+5; 11 12 bool visit[N]; 13 int n; 14 vector<int> a; 15 vector<int> b; 16 vector<int> c; 17 int oushu[N]; 18 19 long long isPrime(long long n) 20 { //返回1表示判断为质数,0为非质数,在此没有进行输入异常检测 21 float n_sqrt; 22 if(n==2 || n==3) return 1; 23 if(n%6!=1 && n%6!=5) return 0; 24 n_sqrt=floor(sqrt((float)n)); 25 for(int i=5;i<=n_sqrt;i+=6) 26 { 27 if(n%(i)==0 | n%(i+2)==0) return 0; 28 } 29 return 1; 30 } 31 32 void solve() { 33 fill(visit, visit+N, false); 34 memset(oushu, 0, sizeof(oushu)); 35 b.clear(); 36 c.clear(); 37 cin >> n; 38 for (int i = n /2; i > 1; i--) { 39 if (isPrime(i)) { 40 a.clear(); 41 a.push_back(i); 42 for (int j = (n / i); j >= 2; j--) { 43 if (!visit[i*j]) { 44 a.push_back(j*i); 45 } 46 } 47 if (a.size() % 2 == 0) { 48 for (int j = 0; j < a.size()/2; j++) { 49 b.push_back(a[j]); 50 c.push_back(a[a.size()-1-j]); 51 visit[a[j]] = true; 52 visit[a[a.size()-1-j]] = true; 53 } 54 } 55 else { 56 for (int j = 0; j < a.size()/2; j++) { 57 b.push_back(a[j]); 58 c.push_back(a[a.size()-2-j]); 59 visit[a[j]] = true; 60 visit[a[a.size()-2-j]] = true; 61 } 62 } 63 } 64 } 65 66 int k = 0; 67 for (int i = n; i > 1; i--) { 68 if (i % 2 == 0 && visit[i] == false) { 69 oushu[k++] = i; 70 } 71 } 72 73 cout << b.size() + k/2 << " "; 74 75 for (int i = 0; i < k/2; i++) { 76 cout << oushu[i] << " " << oushu[k-i-1] << " "; 77 } 78 79 for (int i = 0; i < b.size(); i++) { 80 cout << b[i] << " " << c[i] << " "; 81 } 82 } 83 84 int main() { 85 int t; 86 cin >> t; 87 while (t--) { 88 solve(); 89 } 90 return 0; 91 }