我们首先来看题目:
题目的核心就是要将一个数组循环右移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;
}