cf 432 C

            

              链接: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;
}


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章