PAT 乙等 1008 C语言

1008. 数组元素循环右移问题 (20)


一个数组A中存有N(N>0)个整数,在不允许使用另外数组的前提下,将每个整数循环向右移M(M>=0)个位置,即将A中的数据由(A0 A1……AN-1)变换为(AN-M …… AN-1 A0 A1……AN-M-1)(最后M个数循环移至最前面的M个位置)。如果需要考虑程序移动数据的次数尽量少,要如何设计移动的方法?

输入格式:每个输入包含一个测试用例,第1行输入N ( 1<=N<=100)、M(M>=0);第2行输入N个整数,之间用空格分隔。

输出格式:在一行中输出循环右移M位以后的整数序列,之间用空格分隔,序列结尾不能有多余空格。

输入样例:
6 2
1 2 3 4 5 6
输出样例:
5 6 1 2 3 4


思路:

方法一:将前N-M位逆序,再将后M位逆序,最后再将整个序列逆序。依据:设整个序列分为ab两个部分,a是前N-M位,b是后M位,目标是求ba,则ba = ((a-1)(b-1))-1.

方法二:将序列循环右移M次,每次右移一位。

方法三:取巧,定义数组长度为200,将后N-M位拷贝到N+M位,输出N-M到N+M即可

一、起始变量(方法一)

1.N 数列个数,M右移位数

2.array[N]存储数列

二、计算

1.定义逆序函数,参数为起始位置的数列指针与数列长度

2.依次逆序前N-M位,后M位,整个序列。

3.输出

//方法一 
#include "stdio.h"
void reverse(int * array, int len); 
int main()
{
	int N,M;
	scanf("%d %d",&N,&M);
	int array[N];
	M = M % N;
	for(int i = 0; i < N; i++)
	{
		scanf("%d",&array[i]);
	}
	reverse(array, N - M);
	reverse(array + N - M, M);
	reverse(array, N);
	for(int i = 0; i < N; i++)
	{
		printf("%d",array[i]);
		if(i != N - 1)
		{
			printf(" "); 
		}
	}
	return 0;
}
void reverse(int * array, int len)
{
	int k = len / 2;
	for(int i = 0; i < k; i++)
	{
		int tmp = array[i];
		array[i] = array[len - 1 - i];
		array[len - 1 -i] = tmp;
	}
}


//方法二 
//#include "stdio.h"
//
//int main()
//{
//	int N,M;
//	scanf("%d %d",&N,&M);
//	int array[N];
//	for(int i =0; i < N; i++)
//	{
//		scanf("%d",&array[i]);
//	}
//	for(int i = 0; i < M; i++)
//	{
//		int tmp = array[N - 1];
//		for(int j = N - 1; j > 0; j--)
//		{
//			
//			array[j] = array[j - 1];
//		}
//		array[0] = tmp;
//	}
//	for(int i = 0; i < N; i++)
//	{
//		printf("%d",array[i]);
//		if(i != N - 1)
//		printf(" ");
//	}
//	return 0;
//}


//方法三 
//#include "stdio.h"
//#include "stdlib.h"
//int main()
//{
//	int N = 0;
//	int M = 0;
//	scanf("%d %d",&N,&M);
//	int a[200] = {0};
//	int i ;
//	M = M % N;
//	for (i = 0; i < N ; i++)
//	{
//		scanf("%d",&a[i]);
//		a[N + i] = a[i] ;
//	}
//	
//	for(i = N - M ; i < 2*N - M ; i++)
//	{
//		printf("%d",a[i]);
//		if(i != 2 * N - M - 1)
//		printf(" ");
//	}
//	return 0;
//}


评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值