题目链接
一个数组A中存有N(>0)个整数,在不允许使用另外数组的前提下,将每个整数循环向右移M(≥0)个位置,即将A中的数据由(A0 A1 ⋯AN−1 )变换为(AN−M ⋯AN−1 A0 A1 ⋯AN−M−1 )(最后M个数循环移至最前面的M个位置)。如果需要考虑程序移动数据的次数尽量少,要如何设计移动的方法?
输入格式:
每个输入包含一个测试用例,第1行输入N(1≤N≤100)和M(≥0);第2行输入N个整数,之间用空格分隔。
输出格式:
在一行中输出循环右移M位以后的整数序列,之间用空格分隔,序列结尾不能有多余空格。
输入样例:
6 2
1 2 3 4 5 6
输出样例:
5 6 1 2 3 4
第一遍(有BUG):
#include <iostream>
using namespace std;
int main(){
int n,d;
cin>>n>>d;
int a[n];
for(int i=0;i<n;i++) cin>>a[i];
if(d>=n) d=d%n;
for(int i=0;i<d;i++){
int t[2]={a[0],-1};
for(int j=0;j<n;j++){
int k=j+1;
if(j==n-1) k=0;
t[k%2]=a[k];
a[k]=t[(k+1)%2];
}
}
for(int i=0;i<n;i++){
cout<<a[i];
if(i!=n-1) cout<<" ";
}
}
不用新开数组的解决方案:
想法如上图所示。
交上去系统验证得到AC,但是发现其实有问题,在总数字数为奇数时,会出现末尾数字的丢失。例如:输入数据5 1 1 2 3 4 5的结果为4 1 2 3 4。原因在于最后一位数字的传输出错了,t0被重复使用了,而不是交替。
所以添加一小行代码在程序段中 ,修复上述BUG,得到最终版本:
#include <iostream>
using namespace std;
int main(){
int n,d;
cin>>n>>d;
int a[n];
for(int i=0;i<n;i++) cin>>a[i];
if(d>=n) d=d%n;
for(int i=0;i<d;i++){
int t[2]={a[0],-1};
for(int j=0;j<n;j++){
int k=j+1;
if(j==n-1){
k=0;
if(n%2==1){ //在这里加入一小段代码 是对奇数个数数列的末尾特殊处理
a[0]=t[0];
continue;
}
}
t[k%2]=a[k];
a[k]=t[(k+1)%2];
}
}
for(int i=0;i<n;i++){
cout<<a[i];
if(i!=n-1) cout<<" ";
}
}