题意:
分析:
思维题,原谅我没有思维
我们从大到小枚举质因数,有相同质因数的数可以匹配
对于每一个质因数,若它的倍数中未匹配的个数为偶数,那么两两匹配就是全部消掉了,若个数为奇数,那么将这个质因数的二倍剩下来,其他数两两匹配,为什么这样更优呢?因为我们从小到大枚举质因数,最后剩下的数一定是 2 的倍数,那么最后每个质因数剩下来的数一定会在枚举 2 的时候被匹配到
代码:
#include<bits/stdc++.h>
using namespace std;
namespace zzc
{
inline int read()
{
int x=0,f=1;char ch=getchar();
while (!isdigit(ch)){if (ch=='-') f=-1;ch=getchar();}
while (isdigit(ch)){x=x*10+ch-48;ch=getchar();}
return x*f;
}
const int maxn = 1e5+5;
int n,cnt=0,len,num;
int p[maxn],tmp[maxn],ans[maxn][2];
bool vis[maxn];
void init()
{
for(int i=2;i<=50000;i++)
{
if(!vis[i])
{
p[++cnt]=i;
}
for(int j=1;j<=cnt&&i*p[j]<=50000;j++)
{
vis[i*p[j]]=true;
if(i%p[j]==0) break;
}
}
}
void work()
{
init();
n=read();
memset(vis,false,sizeof(vis));
for(int i=cnt;i;i--)
{
len=0;
for(int j=p[i];j<=n;j+=p[i]) if(!vis[j]) tmp[++len]=j;
if(len&1)
{
swap(tmp[len],tmp[2]);
len--;
}
for(int j=1;j<=len;j+=2)
{
vis[tmp[j]]=vis[tmp[j+1]]=true;
ans[++num][0]=tmp[j];
ans[num][1]=tmp[j+1];
}
}
printf("%d
",num);
for(int i=1;i<=num;i++) printf("%d %d
",ans[i][0],ans[i][1]);
}
}
int main()
{
zzc::work();
return 0;
}