zoukankan      html  css  js  c++  java
  • CF449C Jzzhu and Apples

    传送门

    这道题好像一开始想到了差不多的做法orz?后来都不大敢相信就是这么做的……有点瞎搞。

    后来看了CF的官方题解,感觉还是挺有道理的。首先对于1和大于n/2的质数肯定是不行的,我们直接忽略。然后,对于每一个质数的倍数,我们肯定是把他们组合在一起更优。如果这些数有奇数个,那我们就把质数的2倍挑出来(因为2倍是最容易组合的!)

    如果有偶数个就直接组合。

    最后你肯定剩下的全都是偶数,那么随便组合就行啦!

    直接用两个栈模拟即可。

    看一下代码。

    #include<cstdio>
    #include<algorithm>
    #include<cstring>
    #include<iostream>
    #include<cmath>
    #include<set>
    #include<queue>
    #define pr pair<int,int>
    #define mp make_pair
    #define fi first
    #define sc second
    #define rep(i,a,n) for(int i = a;i <= n;i++)
    #define per(i,n,a) for(int i = n;i >= a;i--)
    #define enter putchar('
    ')
    
    using namespace std;
    typedef long long ll;
    const int M = 200005;
    const int INF = 1000000009;
    
    int read()
    {
        int ans = 0,op = 1;
        char ch = getchar();
        while(ch < '0' || ch > '9')
        {
        if(ch == '-') op = -1;
        ch = getchar();
        }
        while(ch >= '0' && ch <= '9')
        {
        ans *= 10;
        ans += ch - '0';
        ch = getchar();
        }
        return ans * op;
    }
    
    int n,p[M],stack[M],tot,cur,sta[M],cnt,now;
    bool np[M],vis[M];
    pr ans[M];
    
    void euler()
    {
        np[1] = 1;
        rep(i,2,n)
        {
        if(!np[i]) p[++tot] = i;
        for(int j = 1;i * p[j] <= n;j++)
        {
            np[i*p[j]] = 1;
            if(!(i%p[j])) break;
        }
        }
    }
    
    int main()
    {
        n = read();
        euler();
        rep(i,2,tot)
        {
        if(p[i] > n>>1) break;
        rep(j,1,n/p[i]) if(j != 2 && !vis[p[i] * j]) sta[++cur] = p[i] * j,vis[p[i] * j] = 1;
        if(cur&1)
        {
            sta[++cur] = p[i] << 1,vis[p[i] << 1] = 1;
            while(cur) ans[++cnt].fi = sta[cur--],ans[cnt].sc = sta[cur--];
        }
        else
        {
            stack[++now] = p[i] << 1,vis[p[i] << 1] = 1;
            while(cur) ans[++cnt].fi = sta[cur--],ans[cnt].sc = sta[cur--];
        }
        }
        rep(j,1,n>>1) if(!vis[j<<1]) stack[++now] = j << 1;
        if(now&1) now--;
        while(now) ans[++cnt].fi = stack[now--],ans[cnt].sc = stack[now--];
        printf("%d
    ",cnt);
        rep(i,1,cnt) printf("%d %d
    ",ans[i].fi,ans[i].sc);
        return 0;
    }
  • 相关阅读:
    【LeetCode OJ】Remove Element
    【LeetCode OJ】Remove Duplicates from Sorted Array
    【LeetCode OJ】Swap Nodes in Pairs
    【LeetCode OJ】Merge Two Sorted Lists
    【LeetCode OJ】Remove Nth Node From End of List
    【LeetCode OJ】Two Sum
    【LeetCode OJ】Majority Element
    最长公共子序列问题
    php fopen与file_get_contents的区别
    PHP 技巧集合
  • 原文地址:https://www.cnblogs.com/captain1/p/9781303.html
Copyright © 2011-2022 走看看