PAT乙级 1008

173 阅读2分钟

我们首先来看题目:

image.png

题目的核心就是要将一个数组循环右移M个位置(将每个整数循环向右移M(≥0)个位置,即将A中的数据由(A ​0 ​​ A ​1 ​​ ⋯A ​N−1 ​​ )变换为(A ​N−M ​​ ⋯A ​N−1 ​​ A ​0 ​​ A ​1 ​​ ⋯A ​N−M−1 ​​ )(最后M个数循环移至最前面的M个位置) ,这样看着很简单,好像只要下标加上m在模n就好了。但是有一个条件是,不允许使用格外的数组。这样我们不能直接下标加上m模n; ,因为这样会覆盖掉一些数据。那么,我们稍微思考一下,将数组开的很大,大到足够你放下两组数据还有余(不要舍不得空间),在你输入数据时,完全复制一组数组紧接着原始数据。好,接下来我们只需要对复制数据进行移动。

举例:输入样例
6 2
1 2 3 4 5 6

那么其实真实的数组是1 2 3 4 5 6 1 2 3 4 5 6
这个时候对后面的复制数据做处理,经过一个遍历,将他原始数据的下标+m再模n
(以原始数据的下标,表示该向,但是数据是一样的,只是这样即便原始数据下标位置的数据被循环右移的数据所覆盖,但是其数据还保存在复制数组内,依然可以进行循环右移),这样这道题就做好了。代码如下:
//1008 数组元素循环右移问题 (20 分)
//一个数组A中存有N(>0)个整数,在不允许使用另外数组的前提下,将每个整数循环向右移M
#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm>

using namespace std;

const int N = 205;

int a[N],m,n;

//输入
void in(){
    cin >> n >> m;
    for(int i = 0; i < n; i ++){
        cin >> a[i];
        a[i + n] = a[i];//将数组全体往后移动m,先将每一个数组完全复制一份到本数组(后移n位
        }
    }
            

//
void work(){
    for(int i = n; i < 2 * n; i ++)
        a[(i - n + m) % n] = a[i];//循环右移,那么要进行一次取模
    
}

void out(){
    for(int i = 0; i < n - 1; i ++){
        cout << a[i] << " ";
    }
    cout << a[n - 1] << endl;
}

int main(){
    
    in();
    //不允许使用另一个数组
    work();
    out();

    return 0;
}

题目链接