C语言解决PTA1008 数组元素循环右移问题


本博文源于胡凡老师的《算法笔记》,解决这道题目的关键就是先取模,后打印,打印的话直接n-m - n-1打印,然后1再打印0,n-m打印,思路特别清晰,代码也很简洁,清晰易懂
在这里插入图片描述

输入样例:

6 2
1 2 3 4 5 6

输出样例:

5 6 1 2 3 4

核心思想

先取模避免m大于n,然后就开始n-m - n-1的打印,然后1-n-m打印即可。

完整源码

#include<stdio.h>
int main()
{
    int a[110];
    int n,m,cnt = 0;
    scanf("%d%d",&n,&m);
    m = m%n;
    for(int i =0;i<n;i++){
        scanf("%d",&a[i]);
    }
    for(int i = n-m;i<n;i++){
        //输出n-m 号 到 n-1号数字
        printf("%d",a[i]);
        cnt ++;
        if(cnt<n) printf(" ");
    }
    for(int i = 0;i<n-m;i++){
        printf("%d",a[i]);
        cnt++;
        if(cnt<n)printf(" ");
    }
    return 0;
}

方法2最大公约数
在这里插入图片描述

#include<cstdio>
int gcd(int a,int b){//求a和b最大公约数
    if(b==0) return a;
    else return gcd(b,a%b);
}
using namespace std;

int main()
{
    //freopen("C:\\Users\\Administrator\\Desktop\\test\\input.txt","r",stdin);
    int a[110];
    int n,m,tmp,pos,next;
    //tmp 为临时变量,pos存放当前处理的位置,next为下一个要处理的位置
    scanf("%d%d",&n,&m);
    for(int i =0;i<n;i++){
        scanf("%d",&a[i]);
    }
    m = m%n;
    if(m!=0){
        //如果n==0,直接输出输出即可,不需要执行这部分
        int d = gcd(m,n);
        for(int i = n-m;i<n-m+d;i++){//枚举最大一个公约数的范围
            tmp = a[i];//吧当前元素拿走
            pos = i;//记录当前要处理的位置
            do{
                //计算下一个要处理的位置
                next = (pos-m+n)%n;
                //如果下一个位置不是初始点
                //则把下一个位置的元素赋值给当前处理位置
                if(next != i) a[pos] = a[next];
                else a[pos] = tmp;//把一开始拿走的元素赋值给这个空位
                pos = next;
            }while(pos!=i);//循环直到当前处理位置回到初始位置结束
        }
    }
    for(int i =0;i<n;i++){
        //输出数组
        printf("%d",a[i]);
        if(i<n-1) printf(" ");
    }
    return 0;
}

测试效果

在这里插入图片描述