1008 数组元素循环右移问题 (20分)
一个数组A中存有N(>)个整数,在不允许使用另外数组的前提下,将每个整数循环向右移M(≥)个位置,即将A中的数据由(A0A1⋯AN−1)变换为(AN−M⋯AN−1A0A1⋯AN−M−1)(最后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;//将保存的最后一个数放到第一位来 } }