智者常同渡一桥

(lzl)

FROM:lzl
  hi,joyfire,关于中科院的那道题,先求出最大公约数,不妨设最大公约数为m,那么用集体右移的办法,轮回到出发点要经过n/m,出发点只要选择n,n-1,n-2,...,n-m+1,所以不用标记。但是这个猜测我没有证明......干脆来代码,以下是C语言程序,我直接用gdb看的结果。

main(){
  int k=8;
  int n=6;
  int temp;
  int array[20]={1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20};

  while(k>n){
    k-=n;
  }

  if(k==n){
    return 0;
  }

  //在第一轮交换的同时,求出a,n=m*a(m是最大公约数)

  int pos1 = n;
  int pos2 = n-k;
  int a = 1;
  temp = array[pos1-1];

  while(true){
    array[pos1-1] = array[pos2-1];
    pos1 = pos2;
    pos2 -= k;
    a++;

    if(pos2<=0){
      pos2 += n;
    }

    if(pos2==n){
      array[pos1-1] = temp;
    break;
    }

  }
  int m = n/a;
  //m是最大公约数

  for(int i=1;i< m;i++){
    pos1 = n-i;
    pos2 = pos1;
    temp = array[pos1-1];

    for(int j=1; j< a; j++){
      pos2 -= k;

      if(pos2<=0){
        pos2 += n;
      }

      array[pos1-1] = array[pos2-1];
      pos1 = pos2;
    }
    array[pos1-1] = temp;
  }
  return 0;
}

 

Index

中科院研究生考试的算法题(Mar. 26, 2003, by ducktemple joyfire)
  -->进一步说明(Apr. 1, 2003, by joyfire)
  -->智者常同渡一桥(Apr. 2, 2003, by lzl)