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;
}


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