牛客多校(2020第四场)H Harder Gcd Problem

题目链接: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 << "\n";
74 
75     for (int i = 0; i < k/2; i++) {
76         cout << oushu[i] << " " << oushu[k-i-1] << "\n";
77     }
78 
79     for (int i = 0; i < b.size(); i++) {
80         cout << b[i] << " " << c[i] << "\n";
81     }
82 }
83 
84 int main() {
85     int t;
86     cin >> t;
87     while (t--) {
88         solve();
89     }
90     return 0;
91 }

猜你喜欢

转载自blog.csdn.net/Mrwei_418/article/details/108092096