• 博客园logo
  • 会员
  • 众包
  • 新闻
  • 博问
  • 闪存
  • 赞助商
  • HarmonyOS
  • Chat2DB
    • 搜索
      所有博客
    • 搜索
      当前博客
  • 写随笔 我的博客 短消息 简洁模式
    用户头像
    我的博客 我的园子 账号设置 会员中心 简洁模式 ... 退出登录
    注册 登录

陈体胖

  • 博客园
  • 联系
  • 订阅
  • 管理

公告

View Post

PAT 乙级练习 1008 数组元素循环右移问题

PAT 乙级练习 题解合集

本题链接

题目

一个数组A中存有 N(>0)个整数,在不允许使用另外数组的前提下,将每个整数循环向右移M(≥0)个位置,即将A中的数据由(A0A1⋯AN−1A_0A_1\cdots A_{N-1}A0​A1​⋯AN−1​)变换为(AN−M⋯AN−1A0A1⋯AN−M−1A_{N-M}\cdots A_{N-1}A_0A_1\cdots A_{N-M-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

思路

定义函数reverse,接收数组首地址a和数组长度n,作用是将数组内元素逆置。

观察样例,要循环右移M位,假设M < N,那么不考虑元素顺序的话,原来的后M个元素现在全部出现在最前面,而对整个数组进行一次逆置就可以做到这一点。

此时把整个数组分割成 [0,M−1][0, M-1][0,M−1] 和 [M,N−1][M, N-1][M,N−1] 两个部分,可以发现两部分的元素正好和答案所需的结果排列顺序相反,于是对这两部分再分别逆置即可。

代码

#include <stdio.h>

void reverse(int *a, int n) {
	int i, temp;
	for(i = 0; i < n/2; i++){
		temp = a[i];
		a[i] = a[n-i-1];
		a[n-i-1] = temp;
	}
}

int main() {
	int m, n, i;
	scanf("%d %d", &n, &m);
	m %= n;		// 注意,M 可能大于 N 
	int a[n];
	for(i = 0; i < n; i++)
		scanf("%d", &a[i]);
	reverse(a, n);
	reverse(a, m);
	reverse(a + m, n - m);
	for(i = 0; i < n; i++) {
		if(i != 0)
			putchar(' '); 
		printf("%d", a[i]); 
	}
	return 0;
} 

posted on 2020-04-07 17:19  陈体胖  阅读(114)  评论(0)    收藏  举报

刷新页面返回顶部
 
博客园  ©  2004-2025
浙公网安备 33010602011771号 浙ICP备2021040463号-3