1. 程式人生 > 實用技巧 >約瑟夫問題

約瑟夫問題

  約瑟夫問題是個有名的問題:N個人圍成一圈,從第一個開始報數,第M個將被殺掉,最後剩下一個,其餘人都將被殺掉。例如N=6,M=5,被殺掉的順序是:5,4,6,2,3。最後只有1存活。

思路:用環連結串列實現,每計數到M,刪除該處的節點,直到最後僅剩一個節點,輸出節點的值,就是存活的人。

#include<iostream>
using namespace std;
typedef struct Node {
    int data;
    Node *next=NULL;

}Node;

 Node* creatLinkList(int n)
{
    
    Node 
*p = (Node*)malloc(sizeof(Node)); p->data = 1; Node *head = p; for (int i = 2; i <=n; i++) { Node *temp=(Node*)malloc(sizeof(Node)); temp->data = i; p->next = temp; p = p->next; //每新增一個元素i,將p指向新增加的這個節點 } p->next = head; //頭尾相連,成環形連結串列
return head; } int solve(int n,int m) { if (m == 1 || n < 2) return n; Node *list_head = creatLinkList(n); //int i = 0; //while (list_head != NULL&&(i<n)) //{ // i++; // cout << list_head->data; // list_head = list_head->next;
//} Node *cur=list_head; Node *temp = NULL; int count = 1; while (list_head->next!= list_head->next->next) //判斷頭尾是否已經刪到只剩一個節點了 { if (count == m) { temp->next=cur->next; cur = temp->next; count = 1; } else { count++; temp = cur; cur = cur->next; //相當於temp存放的是cur的前一個節點 } } return list_head->next->data; } int main() { int m; int n; cout << "input n and m: " << "n代表環連結串列長度,m代表計數間隔" << endl; cin >> n >> m; int result = solve(n, m); cout << endl<< "result:" << result<<endl; }