数组循环右移(不创建额外数组,程序中数据移动次数尽可能少)
/* PTA上的一道元素循环右移问题,要求不建额外的数组,并且程序中数据移动次数尽可能少
百度到的一些别人写的程序都没注意尽可能少的数据移动次数,这里发表自己的看法,另外
本题强调数组内元素的移动,如果只是要输出移动后的结果,则数组元素不必移动 */
#include <iostream>
using namespace std;
int main(int argc, char *argv[])
{
int n, m;
cin >> n;
cin >> m;
int *a = new int[n];
for (int i = 0; i < n; i++)
{
cin >> a[i];
}
m %= n;
if (m == 0)
{
for (int i = 0; i < n; i++)
{
cout << a[i];
if (i != n - 1) cout << " ";
}
return 0;
}
int pt = n; //pt指向当前需要移动的最后一个元素的后一位
while (m > 0) //m=0时说明已经不需要移动
{
int cnt = 0;
for (int i = 0; i < m && (pt - 1 - i - m) >= 0; i++)
{
int tmp;
tmp = a[pt - 1 - i];
a[pt - 1 - i] = a[pt - 1 - i - m];
a[pt - 1 - i - m] = tmp;
cnt++;
}
m = cnt;
pt -= m;
}
for (int i = 0; i < n; i++)
{
cout << a[i];
if (i != n - 1) cout << " ";
}
return 0;
}
/* 这样最坏情况应该是移动了3*(n-1)<3n次;而如果每次取出最后一位,剩余元素依
次向后移,循环m次的话,移动了m*(n+1)>m*n;所以当m>=3时,这个程序就比较好 */