設有n個人依次圍成一圈,從第1個人開始報數,數到第m個人出列,然後從出列的下一個人開始報數,數到第m個人又出列,…,如此反覆到所有的人全部出列為止。設n個人的編號分別為1,2,…,n,列印出列的順序。
【演算法分析】
本題我們可以用陣列建立標誌位等方法求解,但如果用上資料結構中迴圈鏈的思想,則更貼切題意,解題效率更高。n人圍成一圈,把一人看成一個結點,n人之間的關係採用連結方式,即每一結點有一個前繼結點和一個後繼結點,每一個結點有一個指標指向下一個結點,最後一個結點指標指向第一個結點。這就是單迴圈鏈的資料結構。當m人出列時,將m結點的前繼結點指標指向m結點的後繼結點指標,即把m結點驅出迴圈鏈。
1、建立迴圈連結串列。
當用陣列實現本題鏈式結構時,陣列a[i]作為"指標"變數來使用,a[i]存放下一個結點的位置。設立指標j指向當前結點,則移動結點過程為j=a[j],當數到m時,m結點出鏈,則a[j]=a[a[j]]。 當直接用鏈來實現時,則比較直觀,每個結點有兩個域:一個數值域,一個指標域,當數到m時,m出鏈,將m結點的前繼結點指標指向其後繼結點;
2、設立指標,指向當前結點,設立計數器,計數數到多少人;
3、沿鏈移動指標,每移動一個結點,計數器值加1,當計數器值為m時, 則m結點出鏈,計數器值置為1。
4、重複3,直到n個結點均出鏈為止。
1 #include<iostream> 2 #include<cstdio> 3 using namespace std; 4 int a[10000001]; 5 int tot=1; 6 int main() 7 { 8 int n,m; 9 cin>>n>>m; 10 int j=n; 11 for(int i=0;i<n;i++) 12 { 13 a[i]=i+1; 14 } 15 a[n]=1; 16 int k=1;//報數 17 while(tot<=n) 18 { 19 while(k<m) 20 { 21 j=a[j]; 22 k++; 23 } 24 //cout<<a[j]<<" "; 25 printf("%d ",a[j]); 26 a[j]=a[a[j]]; 27 k=1; 28 tot++; 29 } 30 return 0; 31 }