鏈接:http://codeforces.com/problemset/problem/432/C
任意一個大於2的合數等於兩個素數相加,只要知道這個定理就不難了。將每個元素的值作爲下標,記錄該元素所在的位置,排序的時候判斷該點是否爲本身,不是得話就去判斷兩點之間的距離是否爲素數,不是變爲兩個素數相加即可,具體看代碼
#include <bits/stdc++.h>
using namespace std;
const int maxn=1e5+5;
bool prime[maxn],mark[maxn];
int v[maxn];
void Prime()
{
memset(prime,0,sizeof(prime));
memset(mark,0,sizeof(mark));
memset(v,0,sizeof(v));
for(int i=2;i<maxn;i++)
{
if(!mark[i])
{
prime[i]=1;
for(int k=i;k<maxn;k+=i)
mark[k]=1;
}
}
for(int i=2;i<maxn;i++) //小於等於該值最近的素數
if(prime[i]) v[i]=i;
else v[i]=v[i-1];
}
int a[maxn];
map<int,int>m;
vector<pair<int,int> >ve;
int main()
{
int n;
Prime();
scanf("%d",&n);
for(int i=1;i<=n;i++)
{
cin>>a[i];
m[a[i]]=i;
}
for(int i=1;i<=n;i++)
{
while(m[i]!=i)
{
int t=m[i]-i+1;
int p=m[i]-v[t]+1;
ve.push_back(make_pair(p,m[i]));
m[a[p]]=m[i];
swap(a[m[i]],a[p]);
m[i]=p;
// cout<<m[i]<<" "<<m[a[p]]<<endl;
}
}
cout<<ve.size()<<endl;
for(int i=0;i<ve.size();i++)
cout<<ve[i].first<<" "<<ve[i].second<<endl;
return 0;
}