CF449C Jzzhu and Apples 思維題
阿新 • • 發佈:2020-11-16
題意:
分析:
思維題,原諒我沒有思維
我們從大到小列舉質因數,有相同質因數的數可以匹配
對於每一個質因數,若它的倍數中未匹配的個數為偶數,那麼兩兩匹配就是全部消掉了,若個數為奇數,那麼將這個質因數的二倍剩下來,其他數兩兩匹配,為什麼這樣更優呢?因為我們從小到大列舉質因數,最後剩下的數一定是 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\n",num); for(int i=1;i<=num;i++) printf("%d %d\n",ans[i][0],ans[i][1]); } } int main() { zzc::work(); return 0; }