采用环状替换
#include<cstdio>
const int maxn = 110;
int a[maxn];
int main() {
int n, m;
scanf("%d%d", &n, &m);
for(int i=0;i<n;i++) {
scanf("%d", &a[i]);
}
m %= n;
int count=0;
for(int start=0; count<n; start++) {
int pre = a[start], temp, current = start;
do{
int next = (current+m) % n;
temp = a[next];
a[next] = pre;
current = next;
pre = temp;
count++;
}while(current!=start);
}
for(int i=0; i<n; i++) {
printf("%d", a[i]);
if(i!=n-1) printf(" ");
}
return 0;
}
最容易理解系列:
#include<cstdio>
const int maxn = 110;
int a[maxn];
int main() {
int n, m;
scanf("%d%d", &n, &m);
for(int i=0;i<n;i++) {
scanf("%d", &a[i]);
}
int count = 0;
m %= n;
for(int i=n-m; i<n; i++) {
printf("%d ", a[i]);
count++;
}
for(int i=0;i<n-m;i++) {
printf("%d", a[i]);
count++;
if(count<n) printf(" ");
}
return 0;
}
如果可以使用数组:
参考代码如下:
void rotate(vector<int>& nums, int k) {
int len = nums.size(), temp;
k = k > len ? k % len: k;
while(len -k) {
nums.push_back(nums[0]);
nums.erase(nums.begin());
k++;
}
}
扩展: 环状替换的错误用法;
以下为错误代码, 有兴趣的可以看看
提供一组测试数据
6 5
1 2 3 4 5 6
#include<cstdio>
const int maxn = 1000;
int a[maxn];
int main() {
int n, m;
scanf("%d%d", &n, &m);
for(int i=0;i<n;i++) {
scanf("%d", &a[i]);
}
m %= n;
int temp1, temp2;
for(int j=0;j<m;j++) {
temp1 = a[j];
for(int i=j; i<n-m; i++) {
temp2 = a[i+m];
a[i+m] = temp1;
temp1 = temp2;
}
a[j] = temp1;
}
for(int i=0; i<n; i++){
printf("%d", a[i]);
if(i!=n-1) printf(" ");
}
return 0;
}
环状替换的另一种写法, 循环 最大公约数 次
关于为什么是循环最大公约数次,LeetCode 189 旋转数组的官方题解中有解释
#include<iostream>
using namespace std;
const int maxn = 110;
int list[maxn];
int gcd(int n, int k) {
if(k == 0) return n;
else return gcd(k, n % k);
}
int main() {
int n, move;
cin >> n >> move;
for(int i=0;i<n;i++) {
cin >> list[i];
}
move = move % n;
int temp1, temp2, current, d = gcd(n, move);
for(int i=0; i<d; i++) {
temp1 = list[i];
current = i;
do{
int next = (current + move) % n;
temp2 = list[next];
list[next] = temp1;
temp1 = temp2;
current = next;
}while(current != i);
}
for(int i=0;i<n;i++) {
if(i) cout << " ";
cout << list[i];
}
return 0;
}