歌德巴赫猜想:
任一大于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;
}