美文网首页
2020-02-09

2020-02-09

作者: km15 | 来源:发表于2020-02-09 11:07 被阅读0次

    /*
    题意:
    1、数组循环右移,

    解题:
    1、先算出最大公约数,从n - m到n - m + d - 1枚举起始位
    2、计算下一个位置,当前位置,temp存当前位置元素,不断开始较短

    learn && wrong:
    1、从n - m到n -1会出错的,只要到n - m + d - 1即可
    2、修正m,因为有可能m比n大,没必要浪费那么多次
    3、一趟循环停止,是下一个位置是初始点,就停止
    4、核心代码要好好看一下,
    先计算pos,temp,next,之后就是三行核心代码而已;
    5、next的处理很有意思,不是单纯减m,还要加上n,再余上n;
    */

    #include <iostream>
    using namespace std;
    int  gcd(int a, int b){
        if(b == 0) return a;
        else  return gcd(b, a % b);
    }
    
    int main(int argc, char** argv) {
        int a[110];
        int n,m,temp,pos,next;
        //temp为临时变量,pos存放当前处理的位置,next为下一个要处理的位置
        scanf("%d%d",&n,&m);
        
        for(int i = 0;i < n;++i){
            scanf("%d", &a[i]);
        } 
        
        m = m % n; //修正m,当m大于n时,可以少执行很多次 
        
        if(m != 0) {    //如果m==0,直接输出数组即可,不需要执行这部分 
            int d = gcd(m,n); 
            for(int i = n - m;i < n - m + d;++i){   //枚举一个最大公约数的范围 
                temp = a[i];    //当前位置的元素暂存
                pos = i;    //记录当前处理的位置
                do{
                    //计算下一个要处理的位置
                    next = (pos - m + n) % n;   
                    //如果下一个位置不是初始点
                    //则把下一个位置的元素复制给当前的处理位置
                    
                     if(next != i) a[pos] = a[next];
                     else a[pos] = temp;    //把一开始拿走的元组赋值给最后这个额空位 
                     pos = next;    //传递位置 
                } while(pos != i);  //循环直到当前处理位置回到初始位置结束 
            } 
        } 
        
        for(int i = 0;i < n;++i){
            printf("%d", a[i]);
            if( i < n - 1) printf(" ");
        } 
        return 0;
    }

    相关文章

      网友评论

          本文标题:2020-02-09

          本文链接:https://www.haomeiwen.com/subject/xtegxhtx.html