PAT B1008

采用环状替换

#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;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值