zoukankan      html  css  js  c++  java
  • 2020牛客暑期多校训练营(第四场)H-Harder Gcd Problem(贪心)

    题目链接

    题目大意:把(1)(n)总共(n)个数两两分组,要求分组尽可能多并且每组的(gcd)都大于(1)
    做法大致就是先把所有的素数筛出来,然后先去除所有大于(lfloor frac{n}{2} floor)的素数。对于剩下来的素数对于他所有的倍数且尚未匹配的进行任意匹配,若个数为奇数,则留下他的(2)倍用作后续匹配,最后会剩下一堆偶数,会算在(2)的倍数中,进行任意匹配即可。

    #include <bits/stdc++.h>
    using namespace std;
    const int maxn = 2e5 + 10;
    int prime[maxn];
    bool vis[maxn];
    int ans[maxn << 1];
    int cnt, num;
    void init(){
        for (int i = 2; i < maxn; i++){
            if (!vis[i])prime[++cnt] = i;
            for (int j = 1; j <= cnt && prime[j] * i < maxn; j++){
                vis[prime[j] * i] = 1;
                if (i % prime[j] == 0)break;
            }
        }
    }
    int main(){
        init();
        int t;cin>>t;
        while(t--){
            int n;
            scanf("%d", &n);
            num = 0;
            for (int i = 1; i <= n; i++) vis[i] = false;
            int mx = upper_bound(prime + 1, prime + cnt + 1, n / 2) - prime - 1;
            for (int i = mx; i; i--){
                int pp = prime[i];
                for (int j = pp; j <= n; j += pp){
                    if (vis[j])continue;
                    if (j == pp * 2)continue;
                    ans[++num] = j;
                    vis[j] = true;
                }
                if (num & 1) ans[++num] = pp * 2, vis[pp * 2] = true;
            }
            printf("%d
    ", num >> 1);
            for (int i = 1; i <= num; i += 2)
                printf("%d %d
    ", ans[i], ans[i + 1]);
        }
    }
    
  • 相关阅读:
    其实那女子根本就不是在三楼死的
    ARX工程必须使用release模式编译
    解决64bit不能连接access的问题
    bootstrap例子
    bootstrap登录界面
    Bootstrap3.0入门学习系列教程
    CentOS(Linux)中解决MySQL乱码
    linux yum命令详解
    CentOS yum 安装 Apache + PHP + MySQL
    Centos下配置php环境
  • 原文地址:https://www.cnblogs.com/charles1999/p/13347483.html
Copyright © 2011-2022 走看看