题目大意

给出一个集合的大小n,构造两个一样的集合A和B,分别包含{1,2,...,n}。
对两个集合中的不同数两两组合,每一对gcd(Api,Bqi)>1,求最多有多少对。

解题思路


思路一:
首先应该考虑有那些数不能参与匹配。显而易见1和大于n/2的素数一定没有匹配对象,可以直接忽略。
接下来考虑剩下的素数,倒序枚举每个素数p,找出所有未匹配的p的倍数,并且记下总数。 如果总数是偶数,那么这些数就可以完美两两匹配;否则留下2p(2的倍数最为常用,可以用于应对最后剩下的数),匹配其余的数。
最后只会留下一堆偶数,而它们两两都可以随意匹配。

AC代码


#include<bits/stdc++.h>
using namespace std;
long long a[200010],b[200010];
int main()
{
    int t,n,x,ans,i,j;
    for(i=2;i<=200000;i++)
        if(b[i]==0)
            for(j=2*i;j<=200000;j+=i) b[j]=1;
    scanf("%d",&t);
    while(t--)
    {
        ans=0;
        scanf("%d",&n);
        for(i=2;i<=n;i++) a[i]=0;
        for(i=n;i>=2;i--)
            if(!b[i])
            {
                x=i;
                for(j=n/i*i;j>i;j-=i)
                {
                    if(a[j]) continue;
                    if(x==0) x=j;
                    else ans++,a[x]=j,a[j]=x,x=0;
                }
            }
        printf("%d\n",ans);
        for(i=2;i<=n;i++)
            if(a[i]>i) printf("%d %d\n",i,a[i]);
    }
}