题目链接:http://codeforces.com/problemset/problem/432/C
题意:给出一个大小为n无序数列s,1<si<n,若(i-j+1)为质数,则可以直接交换,要求将其转换为有序数列,且要求交换次数小于5*k
思路:一个数可以分拆为k个质数(k<5),经过多次交换则可以将s[i]与i交换(这个好像是哥尔巴赫猜想),i从一开始交换知道第i位变为有序在进行i+1的交换
#include <iostream>
#include <cstdio>
#include <algorithm>
#include <cstring>
#define maxn 100030
using namespace std;
int s[100030],prime[100030],res=0,pathx[maxn*5],pathy[maxn*5];
void getprime()
{
memset(prime,0,sizeof(prime));
prime[0]=1;
prime[1]=1;
for (int i=2;i<maxn;i++)
{
if (prime[i]==0)
{
for (int j=i*2;j<maxn;j+=i)
prime[j]=1;
}
}
}
void change(int x,int y)
{
if (x==y) return;
else if (x<y) swap(x,y);
for (int i=x;i>y;i--)
{
if (prime[i-y+1]==0)
{
//cout<<x<<":"<<y<<endl;
pathx[res]=y;
pathy[res]=i;
swap(s[y],s[i]);
y=i;
res++;
change(x,y);
break;
}
}
}
int main()
{
int n;
getprime();
while (scanf("%d",&n)!=EOF)
{
res=0;
for (int i=1;i<=n;i++)
{
scanf("%d",&s[i]);
}
for (int i=1;i<=n;i++)
{
while (s[i]!=i) change(s[i],i);
}
printf("%d\n",res);
for (int i=0;i<res;i++)
{
printf("%d %d\n",pathx[i],pathy[i]);
}
}
}