https://ac.nowcoder.com/acm/contest/5669/H
从大到小枚举所有质因子,然后找出n以内的他的倍数的个数
如果是偶数个,直接匹配掉,如果是奇数个,我们只把2*p[i]留下来不匹配
然后把3-n所有质因子枚举完了以后,我们把2的倍数中剩下的没被匹配的匹配
由于每个质因子多出来的数都是2的倍数,把这些剩下的消化掉, 总数肯定是最大的
#include<bits/stdc++.h>
using namespace std;
int vis[200010];
int p[200010],f[200010],tot;
struct Node{
int a,b;
};
void seive(int n){
for(int i=2;i<=n;i++){
if(!f[i])p[tot++]=i;
for(int j=0;j<tot&&i*p[j]<=n;j++){
f[i*p[j]]=1;
if(i%p[j]==0)break;
}
}
}
vector<Node>ans;
int main(){
int t;
seive(200000);
scanf("%d",&t);
while(t--){
int n;
scanf("%d",&n);
for(int i=1;i<=n;i++)vis[i]=0;
ans.clear();
Node t;
t.a=t.b=0;
int i=0;
while(i<tot&&2*p[i]<=n)i++;
i--;
while(i>=0){
int x=p[i];
t.a=x;
vis[x]=1;
for(int j=n/x;j;j--){
if(vis[x*j])continue;
vis[x*j]=1;
if(!t.a)t.a=x*j;
else{
t.b=x*j;
ans.push_back(t);
t.a=t.b=0;
}
}
vis[t.a]=0;
t.a=0;
i--;
}
printf("%d\n",ans.size());
for(int i=0;i<ans.size();i++){
printf("%d %d\n",ans[i].a,ans[i].b);
}
}
}