PAT乙级 1008 数组元素循环右移问题 最大公约数和最小公倍数

在这里插入图片描述

题解:

其实一个数组开大一点也可以过的,并没有限制空间==

#include<iostream>
#include<algorithm>
#include<string>
#include<stdio.h>
using namespace std;

int n,m,a[300];

int main(){
    scanf("%d%d",&n,&m);
    for(int i=0;i<n;i++){
        scanf("%d",&a[i]);
    }
    m=m%n;
    int p1=150,p2=150;
    for(int i=0;i<=n-m-1;i++){
        a[p1++]=a[i];
    }
    for(int i=0;i<m;i++){
        a[i]=a[n-m+i];
    }
    for(int i=m;i<n;i++){
        a[i]=a[p2++];
    }
    for(int i=0;i<n;i++){
        printf("%s%d",i==0?"":" ",a[i]);
    }
    return 0;
}

正解:

#include<iostream>
#include<algorithm>
#include<string>
#include<stdio.h>
using namespace std;

int gcd(int a,int b){
    return b==0?a:gcd(b,a%b);
}

int main(){
    int n,m,temp,pos,next,a[110];
    //temp为临时变量,pos存放当前处理的位置,next为下一个要处理的位置
    scanf("%d%d",&n,&m);
    for(int i=0;i<n;i++){
        scanf("%d",&a[i]);
    }
    m=m%n;//修正m
    if(m!=0){
        int d=gcd(m,n);//d是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("%s%d",i==0?"":" ",a[i]);
    }
    return 0;
}

发布了253 篇原创文章 · 获赞 15 · 访问量 7992

猜你喜欢

转载自blog.csdn.net/weixin_44123362/article/details/103899141