题意:给出n个数,从1到n,求出不互质的数对最多有多少对(每个数只能用一次,且最大公约数大于1)
题解:首先大于n/2的素数肯定不行。
先找出n/2以内的素数,然后从后往前for。
找出p的倍数,如果p的倍数有偶数个(包含p),那么就可以加进去完。
如果有奇数个,那么我们把2*p取出来不管,最后扔给2,贪心下去就行了。
#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<vector>
using namespace std;
vector<int>sp,ans;
int prime[100005],cnt=0,vis[100005],num[100005];
void init(int t){
int i,j;
for(i=2;i<=t;i++){
if(!prime[i])num[++cnt]=i;
for(j=2;j*i<=t;j++){
prime[j*i]=1;
if(!(i%j))break;
}
}
return ;
}
int main(){
int n,i,j;
scanf("%d",&n);
init(n/2);
for(i=cnt;i>=1;i--){
sp.clear();
for(j=num[i]*2;j<=n;j+=num[i]){
if(!vis[j]){
sp.push_back(j);
}
}
sp.push_back(num[i]);
int dt=sp.size();
if(dt%2)j=2;
else j=1;
for(;j<sp.size();j+=2){
ans.push_back(sp[j-1]);
ans.push_back(sp[j]);
vis[sp[j-1]]=1;
vis[sp[j]]=1;
}
}
int dt=ans.size();
printf("%d\n",dt/2);
for(i=1;i<dt;i+=2)printf("%d %d\n",ans[i-1],ans[i]);
return 0;
}