我是靠谱客的博主 执着铃铛,最近开发中收集的这篇文章主要介绍PAT乙级C语言1008 数组元素循环右移问题,觉得挺不错的,现在分享给大家,希望可以做个参考。

概述

1008 数组元素循环右移问题

一个数组A中存有N(>0)个整数,在不允许使用另外数组的前提下,将每个整数循环向右移M(≥0)个位置,即将A中的数据由(A0A​1⋯A​N−1)变换为(A​N−M⋯A​N−1A​0A​1⋯A​N−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
#include<stdio.h>
int main()
{
	int n;//输入n个数
	int m;//输入数向右移
	int a[100];
	
	scanf("%d%d",&n,&m);
	
	for(int i = 0 ; i < n;i++)
	{
		scanf("%d",&a[i]);
	}
	
	if(1 == n)
	{
		printf("%d",a[0]);
	}
	else if(n > m )
	{
		for(int i = n - m ; i < n;i++)
		{
			if (i == n - m)
				printf("%d",a[i]);
			else
				printf(" %d",a[i]);
		}
	
		for(int i = 0; i < n - m;i++)
			printf(" %d",a[i]);
	}
	else if(m % n == 0)
	{
		for(int i = 0;i < n;i++)
		{
			if (i == 0)
				printf("%d",a[i]);
			else
				printf(" %d",a[i]);
		}
	} 
	else
	{
		for(int i = n - m % n ; i < n;i++)
		{
			if (i == n - m % n)
				printf("%d",a[i]);
			else
				printf(" %d",a[i]);
		}
	
		for(int i = 0; i < n - m % n;i++)
			printf(" %d",a[i]);
	}
	return 0;
}

没考虑到一些特殊情况,按着牛客网的测试案例来改的,所以写的繁琐。但是牛客网的有个测试点没过去,pat的能过去,就没继续深究了。

其中取余的想法是从https://blog.csdn.net/qq_40840749/article/details/81781789 以及https://blog.csdn.net/qq_15046309/article/details/86516764 两位博主中的代码看到的。
1)不要想当然地认为N>M,所以在M>N时需要对M进行处理,即作取余计算M=M%N
2)考察的是输出格式的问题,注意一点,即移动的数值会大于原来数组的长度。因此实际的移动数是对数组的长度取余

以及这个博主的想法也可以借鉴,还没有仔细深究。
https://www.cnblogs.com/tenjl-exv/p/9783143.html
思路分析:
  对于循环移动的问题
  将移动个数所在位置左右两边分别反序,再整体反序即可
  PS:
    针对M大于N的情况,取mod(n,m)
    如果向右移动,则从右向左数M
    如果向左移动,则从左向右数M

2022-10-02更新
时隔多年又重新做了这道题。本来想着使用int a[N],输入的时候使用while(N–),结果在尝试输出数组的时候输出为空。再输出N值的时候发现输出为-1。看了眼书中的前半部分,就把数组定义为int a[110]了。这回的思路是,先校正M的值,在输入的时候就输入到它移动后的位置上,最后直接正常输出了。

#include<stdio.h>

int main(){
	int M, N;
	scanf("%d%d", &N, &M);
	int a[110]; 
	int n = M % N;
	for(int i = n; i < N; i++){
		scanf("%d", &a[i]);	
	}
	for(int i = 0; i < n; i++){
		scanf("%d", &a[i]);
	}
	for(int j = 0; j < N; j++){
		if(j != N-1){
			printf("%d ", a[j]);
		}else{
			printf("%d", a[j]);	
		}
	}
	return 0;
}

书中思路:
题目中虽然给出了很多限制,例如不允许使用另外的数组、又要考虑移动数据的次数最少,但实际上却只测试循环右移之后得到的结果而不管过程。

首先需要注意题目并没有给定M的最大值,因此不能直接认为M< N,而需要在读入N和M后令M=M%N,这样就可以保证M<N,使后面操作更简单。这样做的依据是:对一个长度为N的序列,右移N位之后的序列和当前序列是相同的。

在得到新的M后,可以直接输出序列从N-M号元素到N-1号元素,再输出0号元素到N-M-1号元素即可。

最后

以上就是执着铃铛为你收集整理的PAT乙级C语言1008 数组元素循环右移问题的全部内容,希望文章能够帮你解决PAT乙级C语言1008 数组元素循环右移问题所遇到的程序开发问题。

如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。

本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
点赞(41)

评论列表共有 0 条评论

立即
投稿
返回
顶部