00-自測3. 數組元素循環右移問題 (20)

00-自測3. 數組元素循環右移問題 (20)

時間限制
400 ms
內存限制
65536 kB
代碼長度限制
8000 B
判題程序
Standard

一個數組A中存有N(N>0)個整數,在不允許使用另外數組的前提下,將每個整數循環向右移M(M>=0)個位置,即將A中的數據由(A0A1……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
採用實驗指導書思考題的方法,使移動次數不超過2N次。

分析每個數據與目標位置之間的下標關係,將每個數據一次性定位。

#include<iostream>
using namespace std;

#define Swap(a,b) a^=b,b^=a,a^=b;	//連續3次異或運算交換a與b
int gcd(int a,int b){				//gcd算法求最大公約數
	return a==0 ? b : gcd(b%a,a);
}

int main()
{
	int i,j=0,N,M,temp,flag;
	int c[100];
	cin>>N>>M;
	for(i=0;i<N;i++){
		cin>>c[i];
	}
	if(M>N)  M = M % N;				//M>N的處理
	int t=gcd(N,M);					//移動環的個數
	for(i=0;i<t;i++){
		temp=c[i];
		int k=i;
		flag=(i-M+N)%N;				//將要移到第i位置的數據位置
		if(flag==i)					//M爲N的整數倍時,不用移動
			break;
		int n=0,m=0;				//while循環的跳出標誌
		while(!n){			
			Swap(c[k],c[flag]);
			if(m==1)
				n=1;
			else{
				k=flag;
				flag=(k-M+N)%N;
				if(flag==(i+M)%N)	//檢測第i位置數據將移入的位置時再進行一次交換
					m++;
			}
		}
		c[flag]=temp;
	}
	for(i=0;i<N-1;i++)
		cout<<c[i]<<" ";
	cout<<c[i]<<endl;
	return 0;
}



發佈了39 篇原創文章 · 獲贊 9 · 訪問量 2萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章