Codeforces 450E:Jzzhu and Apples(构造,数学)

E. Jzzhu and Apples

time limit per test: 1 secondsios

memory limit per test: 256 megabytesc++

input: standard input数组

output: standard outputapp

Jzzhu has picked \(n\) apples from his big apple tree. All the apples are numbered from \(1\) to \(n\). Now he wants to sell them to an apple store.spa

Jzzhu will pack his apples into groups and then sell them. Each group must contain two apples, and the greatest common divisor of numbers of the apples in each group must be greater than \(1\). Of course, each apple can be part of at most one group.code

Jzzhu wonders how to get the maximum possible number of groups. Can you help him?ci

Input

A single integer \(n (1 ≤ n ≤ 10^5)\), the number of the apples.get

Output

The first line must contain a single integer \(m\), representing the maximum number of groups he can get. Each of the next m lines must contain two integers — the numbers of apples in the current group.input

If there are several optimal answers you can print any of them.it

input

6

output

2
6 3
2 4

input

9

output

3
9 3
2 4
6 8

input

2

output

0

题意

给出正整数\(n\),求出\(\left[1,n\right]\)之间的正整数有多少对数字的最大公约数不等于\(1\),输出最多的组数,并按任意顺序输出这些数字

思路

要使\(gcd(x,y)>1\),那么\(x,y\)中的较小的数必定不大于\(n/2\),因此咱们首先筛出来\([1,n/2]\)范围内的素数

筛出来素数以后,每次在取数的时候,要保证取完数以后,不会使总的符合要求的数对减小,因此咱们从最大的素数(假设为\(x\))开始枚举,可以整除\(x\)的整数必定使最少的,并且不会影响到别的数对(感性理解一下:由于枚举到了\(n/2\),因此\(n/x<=3\)\(2\)的倍数仍是不少的减小一个没什么影响,\(n/x=3\)时,大概只有\(n=9\)的时候,那么也是不会产生影响的)

而后去统计当前素数\(p\)的倍数个数\(num\),若是\(num\)是偶数,直接匹配(为了简便,就相邻的两个数组成一对)

若是\(num\)是奇数,咱们能够将\(p\)\(2\)倍和\(num\)倍交换位置,这样匹配完剩下的那个数能够去和\(2\)的倍数来匹配,这样能够达到最优

代码

#include <bits/stdc++.h>
#define ll long long
#define ull unsigned long long
#define ms(a,b) memset(a,b,sizeof(a))
const int inf=0x3f3f3f3f;
const ll INF=0x3f3f3f3f3f3f3f3f;
const int maxn=1e6+10;
const int mod=1e9+7;
const int maxm=1e3+10;
using namespace std;
int vis[maxn];
int prime[maxn];
int cnt;
int a[maxn];
void get_prime(int n)
{
    vis[0]=vis[1]=1;
    for(int i=2;2*i<=n;i++)
        if(!vis[i])
            for(int j=2;j*i*2<=n;j++)
                vis[j*i]=1;
    for(int i=2;2*i<=n;i++)
        if(!vis[i])
            prime[cnt++]=i;
}
int main(int argc, char const *argv[])
{
    #ifndef ONLINE_JUDGE
        freopen("/home/wzy/in", "r", stdin);
        freopen("/home/wzy/out", "w", stdout);
        srand((unsigned int)time(NULL));
    #endif
    ios::sync_with_stdio(false);
    cin.tie(0);
    int n;
    cin>>n;
    get_prime(n);
    ms(vis,0);
    vector<pair<int,int> >ve;
    for(int i=cnt-1;i>=0;i--)
    {
        int tot=0;
        for(int j=prime[i];j<=n;j+=prime[i])
            if(!vis[j])
                a[++tot]=j;
        // 若是倍数有奇数个,交换第二个和最后一个
        if(tot&1)
            swap(a[2],a[tot]);
        for(int j=1;j+1<=tot;j+=2)
        {
            vis[a[j]]=vis[a[j+1]]=1;
            ve.push_back({a[j],a[j+1]});
        }
    }
    cout<<ve.size()<<endl;
    for(auto i:ve)
        cout<<i.first<<" "<<i.second<<endl;
    #ifndef ONLINE_JUDGE
        cerr<<"Time elapsed: "<<1.0*clock()/CLOCKS_PER_SEC<<" s."<<endl;
    #endif
    return 0;
}
相关文章
相关标签/搜索