天天看點

算法-約瑟夫環問題1.問題:知識點:

1.問題:

請注意:這一節部分隻有

count_off

函數部分可以修改,要先了解其他部分在做什麼後再下手實作

count_off

函數喔

在學習了連結清單結構後,這一節我們需要用連結清單解決一個稍有改動的“約瑟夫環(Josephus problem)”問題:

計算理工學院有 N 個同學,圍成了一個圓圈,每人被順序地編了一個序号(分别為 1,2,3... n1,2,3...n),從編号為 K 的人開始報 1,他之後(順初始數字增長方向計算序号)的人報 2,以此類推,數到某一個數字 M 的人出列。出列同學的下一個人又從 1 開始繼續報數,數到某一個數字 M 的人出列。不斷重複這一過程,直到所有人都出列為止。

你需要根據同學人數 N 和給出的 K 和 M 計算出同學的正确出列順序。

這一題的

main

函數已經幫你寫好了,同時,已經幫你定義了一個節點的結構體類型、通過

circle_create

建立了一個循環連結清單。

現在請在

count_off

函數中根據傳入的編号為 1 的節點 headhead、學生數 n、起始報數學生編号 k、數到出列的數字 m 實作報數的過程,按照題目要求進行輸出。

輸入格式

測評機會反複運作你的程式。每次程式運作時,輸入為一行,包括三個被空格分隔開的符合描述的正整數 N、K 和 M(1<= K<= N<= 10001≤K≤N≤1000,1 <= M <= 20001≤M≤2000)。

輸出格式

輸出為一行,包含 N 個整數,為依次順序出列的學生編号,由空格分隔開。

樣例輸入1

9 1 1      

樣例輸出1

1 2 3 4 5 6 7 8 9      

樣例輸入2

8 5 2      

樣例輸出2

6 8 2 4 7 3 1 5      

知識點:

1.指針

2.連結清單

3.動态記憶體配置設定 ,動态記憶體釋放

重點:

    1.需要考慮到頭尾相接的問題

    2.需要得到目前人的上一個人的指針(非常重要,我就是沒注意到這一點,卡了半小時找問題)

具體代碼如下:

#include <stdio.h>
#include <stdlib.h>
typedef struct node {
    int data;
    struct node *next;
} Node;

Node *circle_create(int n);
void count_off(Node *head, int n, int k, int m);

int main() {
    int n, k, m;
    scanf("%d%d%d", &n, &k, &m);
    Node *head = circle_create(n);
    count_off(head, n, k, m);
    return 0;
}

Node *circle_create(int n) {
    Node *temp, *new_node, *head;
    int i;

    // 建立第一個連結清單節點并加資料
    temp = (Node *) malloc(sizeof(Node));
    head = temp;
    head->data = 1;

    // 建立第 2 到第 n 個連結清單節點并加資料
    for(i = 2; i <= n; i++) {
        new_node = (Node *) malloc(sizeof(Node));
        new_node->data = i;
        temp->next = new_node;
        temp = new_node;
    }

    // 最後一個節點指向頭部構成循環連結清單
    temp->next = head;

    return head;
}

void count_off(Node *head, int n, int k, int m) {
    Node *tempk = head;
    Node *lasttemp = head;
    if(tempk->data == k){
        //如果是頭部,則循環到最後一個
        for(int j=0;j<n;j++){
            if(j == n-1){
                break;
            }
            lasttemp = lasttemp->next; 
        }
    }else{
        for(int i=0;i<n;i++){
            if(tempk->data == k-1){
                lasttemp = tempk;
                tempk = tempk->next;
                break;
            }
            tempk = tempk->next;
        }
    }
    Node *temp = tempk;
    for(int i = 0;i<n;i++){
        for(int j = 0;j<m;j++){
            if(j == m-1){
                printf("%d",temp->data);
                if(i!=n-1) printf(" ");
                if(temp == head){
                    tempk = head;
                    lasttemp->next = head->next;
                    head = head->next;
                    temp = head;
                }   
                else{
                    tempk=temp;
                    lasttemp->next = temp->next;
                    temp=temp->next;   
                }
                free(tempk);
                tempk = NULL;    
                break;
            }else{
                lasttemp = temp;   
                temp = temp->next;
            }
        }
    }
    return;
}
           

繼續閱讀