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

思路:

  • 每一个位置存储的数右移应该被存在: next=(current+m)%n ;
  • 当不停通过当前位置找下一个位置时,可能形成部分位置的闭合循环,如:int record[6]={0,1,2,3,4,5} 将该序列右移两位有:0->2->4->0 ;1->3->5->1;所以要用 flag[] 标记已经被移动过的位置,当形成闭合环时,找下一个没被标记过的位置重新开始循环;如此往复,直到所有的位置均被标记过,最后正常输出;

代码

#include<cstdio>
using namespace std;
int record[101];
int flag[101]={0};
int n,m;
int main(){
    scanf("%d %d",&n,&m);
    for(int i=0;i<n;i++)
        scanf("%d",&record[i]);
    for(int i=0;i<n;i++){
    	//用 flag[] 来寻找还未被移动过的闭合环;
        if(flag[i]==0){
            //用 temp1 存储即将要右移的值;
            int temp1=record[i];
            //用 temp2 作为 temp1 与数组目标位置交换的中间变量;
            int temp2;
            //初始化本轮循环开始时的当前位置 pos 和目标位置 next;
            int pos=i;
            int next=(pos+m)%n;
            //进入循环右移,直到目标位置已被标记,表示循环闭合时退出;
            while(flag[next]==0){
                temp2=record[next];
                record[next]=temp1;
                temp1=temp2;
                //注意一定是标记 next,若标记 pos 会造成闭合前的最后一次移动无法进行;
                flag[next]=1;
                pos=next;
                next=(pos+m)%n;
            }
        }
    }
    for(int i=0;i<n;i++){
        printf("%d",record[i]);
        if(i!=n-1) printf(" ");
    }
    return 0;
}
发布了5 篇原创文章 · 获赞 10 · 访问量 704

猜你喜欢

转载自blog.csdn.net/qq_41379576/article/details/105158269