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;
}
相關文章
相關標籤/搜索