码迷,mamicode.com
首页 > 编程语言 > 详细

数组元素循环右移问题 (20)

时间:2015-06-04 15:04:09      阅读:139      评论:0      收藏:0      [点我收藏+]

标签:

输入格式:每个输入包含一个测试用例,第1行输入N ( 1<=N<=100)、M(M>=0);第2行输入N个整数,之间用空格分隔。  
  
输出格式:在一行中输出循环右移M位以后的整数序列,之间用空格分隔,序列结尾不能有多余空格。  
  
输入样例:  
6 2  
1 2 3 4 5 6  
输出样例:  
5 6 1 2 3 4  

本题要求不能使用新的数组,要做出优秀的算法不太简单。。。

循环右移n个元素,那么复杂度最小应该可以做到O(N)

那么可以先求出M和N的最大公约数gcd

gcd为多少,移动的元素就构成了多少个circle。按上面的例子,6,2的gcd是2,数组中的元素其实是分成了两组来移动的,1,3,5一组,2,4,6一组

我们就可以按照这个方法来设计移动的方法了。

最后写出来的程序,时间O(N),空间O(1),每一个circlr只需移动 n/gcd+1次元素。移动次数不可能比这个更低了

贴代码

#include <stdio.h>
#include <stdlib.h>
int n,m,*a;
int gcd(int a,int b)
{
  if(a%b==0){
    return b;
  }
  return gcd(b,a-a/b*b);
}
int main(void)
{
  scanf("%d%d",&n,&m);
  m=m%n;
  a=(int *)malloc(n*sizeof(int));
  for(int i=0;i<n;i++){
    scanf("%d",&a[i]);
  }
  int time=gcd(m,n);
  int temp,j;
  for(int i=0;i<time;i++){
    temp = a[i];
    j=i;
    while(1){
      a[j]=a[(j+n-m)%n];
      j=(j+n-m)%n;
      if(j==(i+m)%n){
        a[j]=temp;
        break;
      } 
    } 
  }
  printf("%d",a[0]);
  for(int i=1;i<n;i++){
    printf(" %d",a[i]);
  }
}

数组元素循环右移问题 (20)

标签:

原文地址:http://www.cnblogs.com/zhouyiji/p/4551614.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!