• CF 449C


    CF上的题一向都是非常灵活的,很注重想法,而不是依赖固定的算法。

    今天做了一道,虽然只是C难度的题,但是也还是做了将近3个小时。

    说说题吧。

    题目就是说有n个数,每两个数分成一堆,条件是这两个数GCD不能小于2.问最多可以分多少堆。

    我刚开始就想,要先求出素数,然后根据每个素数分成几份,从最大的数开始,依次找到2,其中以前分过的数不可以再分。如果一份数的个数是奇数,就把一个偶数踢出去。最后在计算每一份有多少对,然后相加。

    #include <iostream>
    #include <cstdio>
    #include <cmath>
    #include <cstring>
    using namespace std;
    const int maxn = 100010;
    
    int v[maxn];
    int prim[maxn];
    int num, sum[maxn];
    
    void prime(int n)
    {
    num = 0;
    memset(v, 0, sizeof(v));
    for(int i = 2; i <= n; i++)
    if(!v[i])
    {
    v[i] = 1;
    sum[num] = n / i;
    prim[num++] = i;
    for(int j = i * 2; j <= n; j += i)
    v[j] = 1;
    }
    }
    
    int main()
    {
    int n;
    while(cin >> n)
    {
    int ans = 0;
    int used2 = 0;
    num = 0;
    prime(n);
    memset(v, 0, sizeof(v));
    
    for(int i = num - 1; i >= 0; i--)
    {
    int t = 0;
    for(int j = 1; j <= sum[i]; j++)
    if(!v[j * prim[i]])
    {
    t++;
    v[j * prim[i]] = prim[i];
    //cout << j * prim[i] << " " << prim[i] << " ";
    }
    // cout << t << endl;
    ans += t / 2;
    if(t % 2 && t > 1)
    {
    v[2 * prim[i]] = 0;
    }
    /*for(int i = 2; i <= n; i++)
    cout << v[i] << " ";
    cout << endl << endl;*/
    }
    printf("%d
    ", ans);
    
    for(int i = num - 1; i >= 0; i--)
    {
    int sum1 = 0;
    for(int k = prim[i]; k <= n; k += prim[i])
    if(v[k] == prim[i])
    if(!sum1)
    {
    sum1 = k;
    
    }
    
    else
    {
    printf("%d %d
    ", sum1, k);
    sum1 = 0;
    }
    }
    }
    }
    View Code
  • 相关阅读:
    汉语-词语:理解
    汉语-词语:头脑
    SELECT INTO
    SELECT
    scp
    samba
    rpmgraph
    rpmdeps
    rpmcache
    rpmbuild
  • 原文地址:https://www.cnblogs.com/ye8370/p/3858490.html
Copyright © 2020-2023  润新知