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

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

输入格式:

每个输入包含一个测试用例,第1行输入N(1)和M(≥);第2行输入N个整数,之间用空格分隔。

输出格式:

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

输入样例:

6 2
1 2 3 4 5 6
	

输出样例:

5 6 1 2 3 4
#include<iostream>//思路:利用一个队列,先逆序全部进队,然后不断出队进队M次,最后队列里剩下的出队,然后逆序保存即为所求
#include<queue>
#include<vector>
using namespace std;
int main()
{
	int n,m;
	queue<int> q;
	vector<int>c;
	
	while (cin >> n >> m)
	{
		int x;
		c.clear();
		for (int i = 0; i < n; i++)
		{
			cin >> x;
			c.push_back(x);
		}
		if (m % n == 0)//小技巧加快速度,当是n的倍数时,不用移动,直接输出当前数组
		{
			for (int i = 0; i < n; i++)
			{
				if (i != 0)
					cout << " " << c[i];
				else
					cout << c[i];
			}
		}
		else
		{
			m %= n;//m不是n的倍数时,对其取余,移动m次其实就是移动m%=n次
			while (!q.empty())q.pop();
			for (int i = n - 1; i >= 0; i--)//逆序入队
			{
				q.push(c[i]);
			}
			while (m--)//移位m次
			{
				int z = q.front();//出队然后入队算1次
				q.pop();
				q.push(z);
			}
			c.clear();//清空数组
			while (!q.empty())
			{
				int z = q.front();
				c.insert(c.begin(), z);//头插法保存到数组中
				q.pop();
			}
			for (vector<int>::iterator it = c.begin(); it != c.end(); it++)
			{//遍历
				if (it != c.begin())
					cout << " " << *it;
				else
					cout << *it;
			}
			cout << endl;
		}
	}
	vector<int>().swap(c);//释放内存
	return 0;
}
代码二:运用指针
#include<iostream>
using namespace std;
void fun(int*q,int n, int m);
int main()
{
	int n, m;
	while (cin >> n >> m)
	{
		int* p = new int[n];
		for (int i = 0; i < n; i++)
				cin>> p[i];
		fun(p, n,m);
		for (int i = 0; i < n; i++)
		{
			if (i != 0)
				cout << " " << p[i];
			else
				cout << p[i];
		}
		delete[]p;
	}
	return 0;
}
void fun(int* q,int n, int m)//右移函数
{
	
	while (m--)//循环m次,其实这里也可以加上上面一个代码里的小技巧,对m的处理,加快速度
	{
		int* a = (q + n - 1), temp;//令指针a=q[len],即最后一个数
		temp = *a;//temp保存最后一个数
		for (; a >q; a--)//所有数后移,因为当a=&q[1]时 移完,所以a>&q[0]
		{
			*a = *(a - 1);	
		}
		*a = temp;//将保存的最后一个数放到第一位来
	}
}