这题由一个推导公式的: 事实上,给出1到n的逆序排列,最少需要Ceil[(n+1)/2]次块移动就可以完成排序(除了n=1或n=2,Ceil表示取上整)。当n为奇数时,一个满足要求的算法是:每一次把数字n后面那一段的正中间两个元素拿出来,插入到数字n前面那一段数的正中间。当数字n后面的数被移动完了后,把它前面n-1个数左右两半对换一下就行了。例如,当n=7时:
算法的移动步数显然为(n+1)/2,其正确性可以用数学归纳法说明,这里不再详细叙述了。 也就是说,从n/2到n 一次拿出2个数放到第0位,第1位,第2位。。。。一次类推,走完一遍后直接把从n/2到n-1的数子(例子中123)放在第0位就得到倒序数列了。。。。 有了这一推论,这题就好做了,直接给代码:
#include<stdio.h> int main(){ int i,n; while(scanf("%d",&n)!=EOF){ if(n%2!=0){ if(n==1){ printf("0/n"); } else{ printf("%d/n",(n+1)/2); for(i=n/2+1;i<=n-1;i++){ printf("%d %d %d/n",i,2,i-n/2-1); } printf("%d %d %d/n",n/2+1,n/2,0); } } else if(n%2==0){ if(n==2) printf("1/n2 1 0/n"); else{ printf("%d/n",n/2+1); for(i=n/2;i<=n-2;i++){ printf("%d %d %d/n",i,2,i-n/2); } printf("%d %d %d/n",n/2,n/2-1,0); printf("%d %d %d/n",n,1,0); } } } return 0; } |