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

 

你可能感兴趣的:(codeforces)