約瑟夫環問題——初步瞭解+陣列實現

bigface1234fdfg發表於2015-01-03

約瑟夫環問題——初步瞭解+陣列實現

  

    一開始接觸約瑟夫環問題,還是在C語言的書中,具體的題目如下:n個人圍坐成一圈,選某個人開始(比如第1個),從1開始報數,沿著順時針方向數到m的人被淘汰,然後後面一個人繼續再從1開始報數,數到m時再淘汰一人。重複上面的過程,輸出剩下的最後一個人。


    解題思路:


                 Step 1:建立一個長度為n的陣列;

                 Step 2:刪除的位置編號為i = (i + m -1) % n; 為什麼呢?因為第一個人事i = 0,然後 i 增加m-1即可刪除另外一個人,把陣列想象成一個“環”即可。

                 Step 3:刪除 i 之後,後面的陣列元素往前移動;

                 Step 4:當 i 正好是陣列中最後一個數,刪除之後,由於後面的新的 i 無法移動(後面沒有數了),所以令 i =0; 



程式碼實現如下,這個是用陣列實現的:


#include <iostream>
using namespace std; 

int main()
{
	int m, n; 
	cin >> n >> m; 

	int *p=new int[n]; 
	int i; 
	for(i = 0; i < n; i++)  //初始化
	{
		p[i]=i + 1; 
	}

	while(n > 1)
	{
		i = (i + m - 1) % n;   //找到需要刪除的位置
		cout << p[i] << "被刪除" <<endl; 
		for(int j = i + 1; j < n; j++)  //只能是j=i+1
		{
			p[j - 1]=p[j]; 
		}

		n--; 
		if(i == n)  //如果刪除的是最後一個元素,那麼需要把i重新置為0
		{
			i = 0; 
		}
	}

	cout << "剩下的是" << p[i] <<endl; 

	delete []p; 

	return 0; 
}



結果如下:



此外,還可以用連結串列、佇列、堆疊等實現,後面再寫。



相關文章