codeforces C. Prime Swaps

 题意:给你n个数,然后在交换次数小于等于5×n的情况下使得这个序列变成升序,输出次数;

思路:哥德巴赫猜想:任何一个大于5的数都可以写成三个质数之和。尽可能的找大的素数,从1的位置向右逐步的调整,每一个位置最多5次,有的位置不到5次;

 1 #include <cstdio>
 2 #include <cstring>
 3 #include <algorithm>
 4 #include <cmath>
 5 #define maxn 100010
 6 using namespace std;
 7 
 8 int n;
 9 int a[maxn+10];
10 bool vis[maxn+10];
11 int f[maxn+10];
12 int p[maxn];
13 int s[maxn*5],e[maxn*5];
14 int cnt=0;
15 int bs(int x,int l,int r)
16 {
17     int pos=0;
18     while(l<r)
19     {
20         int mid=(l+r)/2;
21         if(f[mid]>x)
22         {
23             r=mid;
24         }
25         else
26         {
27             l=mid+1;
28             pos=l;
29         }
30     }
31     return pos;
32 }
33 void get_prime()
34 {
35     vis[1]=true;
36     vis[0]=true;
37     for(int i=2; i<maxn; i++)
38     {
39         if(!vis[i])
40         {
41             for(int j=i*2; j<maxn; j+=i)
42             {
43                 vis[j]=true;
44             }
45         }
46     }
47     for(int i=2; i<maxn; i++)
48     {
49         if(!vis[i])
50         {
51            f[cnt++]=i;
52         }
53     }
54 }
55 
56 int main()
57 {
58     get_prime();
59     scanf("%d",&n);
60     for(int i=1; i<=n; i++)
61     {
62         scanf("%d",&a[i]);
63         p[a[i]]=i;
64     }
65     int ans=0;
66     for(int i=1; i<=n; i++)
67     {
68         while(a[i]!=i)
69         {
70            int t=bs(p[i]-i+1,0,cnt-1);
71            t--;
72            int sx=p[i],ex=p[i]-f[t]+1;
73            swap(a[sx],a[ex]);
74            swap(p[a[sx]],p[a[ex]]);
75            s[ans]=sx; e[ans++]=ex;
76         }
77     }
78     printf("%d\n",ans);
79     for(int i=0; i<ans; i++)
80     {
81         printf("%d %d\n",e[i],s[i]);
82     }
83     return 0;
84 }
View Code

 

posted @ 2015-03-06 09:56  null1019  阅读(190)  评论(0编辑  收藏  举报