Codefoces 432 C. Prime Swaps
歌德巴赫猜想:
任一大于5的整数都可写成三个质数之和。
贪心取尽可能大的素数.....
#include <iostream> #include <cstdio> #include <cstring> #include <algorithm> using namespace std; const int maxn=100100; bool vis[maxn]; int prime[maxn/10],pn; int n,a[maxn],b[maxn]; int Left[maxn*5],Right[maxn*5],nu; void get_prime() { for(int i=2;i*i<maxn;i++) { for(int j=i*2;j<maxn;j+=i) { vis[j]=1; } } for(int i=2;i<maxn;i++) { if(vis[i]==0) prime[pn++]=i; } } int Bin(int x) { int low=0,high=pn-1,mid,ans=-1; while(low<=high) { mid=(low+high)/2; if(prime[mid]<=x) { ans=prime[mid],low=mid+1; } else high=mid-1; } return ans; } void debug() { cout<<"a....\n"; for(int i=1;i<=n;i++) cout<<a[i]<<","; cout<<endl; cout<<"b....\n"; for(int i=1;i<=n;i++) cout<<b[i]<<","; cout<<endl; } int main() { get_prime(); scanf("%d",&n); for(int i=1;i<=n;i++) { scanf("%d",a+i); b[a[i]]=i; } for(int i=1;i<=n;i++) { /// from b[i] to i greedy!!! int len=b[i]-i+1; while(len!=1) { int bin=Bin(len); int cp=b[i]-bin+1; /// changepos Left[nu]=cp,Right[nu]=b[i]; nu++; int t1=b[i],t2=b[a[cp]]; swap(a[cp],a[b[i]]); b[a[b[i]]]=t1;b[i]=t2; // debug(); getchar(); len=b[i]-i+1; } } printf("%d\n",nu); for(int i=0;i<nu;i++) { printf("%d %d\n",Left[i],Right[i]); } return 0; }