先找到n的位置i, 判断n-i+1是否为素数,若是直接交换位置,若不是找到最大的素数m, m < n-i+1, 交换i, 和i+m-1位置的数,循环操作
#include <bits/stdc++.h>
#define maxn 100005
#define MOD 1000000007
using namespace std;
typedef long long ll;
int prime[maxn], cnt, num[maxn], p[maxn], k[maxn];
int n;
vector<int> v;
void Prime(){
for(int i = 2; i <= n; i++){
if(prime[i] == 0){
num[cnt++] = i;
for(ll j = (ll)i * i; j <= n; j += i){
prime[j] = 1;
}
}
}
}
int main(){
// freopen("in.txt", "r", stdin);
int ans = 0;
scanf("%d", &n);
Prime();
for(int i = 1; i <= n; i++){
scanf("%d", k+i);
p[k[i]] = i;
}
for(int i = n; i >= 1; i--){
if(p[i] != i){
int m = i - p[i] + 1;
while(m > 1){
int dis = i - p[i];
int h = lower_bound(num, num+cnt, m) - num;
if(num[h] != m){
h--;
dis = num[h] - 1;
}
int d1 = k[p[i]], d2 = k[p[i]+dis];
v.push_back(p[i]);
v.push_back(p[i]+dis);
swap(k[p[i]], k[p[i]+dis]);
p[i] = p[i] + dis;
p[d2] -= dis;
m = i - p[i] + 1;
ans++;
}
}
}
printf("%d\n", ans);
for(int i = 0; i < v.size(); i += 2){
printf("%d %d\n", v[i], v[i+1]);
}
return 0;
}