CF449C:Jzzhu and Apples——题解
https://vjudge.net/problem/CodeForces-449C
题目大意:1-n编号的苹果两两一对,他们的最大公约数不为1,求这些对的最大匹配。
————————————————————————————————
我们显然先把素数筛出来。
然后我们从后往前循环素数p,然后p,2p,3p(取过的自动不要)……这些数两两都可以成一对。
但是如果是奇数个,我们就抛掉2p,因为2p一定可以与其他2的倍数一对。
不知道怎么证明……
#include<cstdio> #include<cstring> #include<vector> #include<iostream> #include<algorithm> https://vjudge.net/problem/CodeForces-449Cusing namespace std; typedef long long ll; const int N=1e5+1; int su[N]; bool he[N]; void Eratosthenes(int n){ for(int i=2;i<=n;i++){ if(he[i]!=0)continue; for(int j=2;j*i<=n;j++)he[j*i]=1; } return; } vector<int>a; int p[N][2]; bool ok[N]; int main(){ int n; scanf("%d",&n); Eratosthenes(n); int ans=0; for(int i=n/2;i>=2;i--){ if(he[i])continue; a.clear(); for(int j=i;j<=n;j+=i){ if(!ok[j]){ a.push_back(j); } } if(a.size()%2)swap(a[1],a[a.size()-1]); for(int j=0;j<a.size()-1;j+=2){ ans++; p[ans][0]=a[j];ok[a[j]]=1; p[ans][1]=a[j+1];ok[a[j+1]]=1; } } printf("%d\n",ans); for(int i=1;i<=ans;i++){ printf("%d %d\n",p[i][0],p[i][1]); } return 0; }