约瑟夫问题

今天弄一弄约瑟夫问题。先百度百科一下。

著名犹太历史学家 Josephus ...

总体大意就是

1~41 到了41后从头循环

由1开始报数,数到3则这个数出列,然后由下一个从1开始数

直到剩最后两个数停止

最后这两个数分别是多少?


思路
其实难点就是用程序数数字的时候别数错了。

使用单循环链表就行,对链表进行简单的删除操作。




实现
代码:

#include <stdio.h>
#include <stdlib.h>

typedef struct List{
    int num;
    struct List* next;
}List, *PList;

PList create(int no)
{
    PList p = malloc(sizeof(List));
    if(p == NULL){
        printf("Out of space");
        exit(1);
    }
    p->next = NULL;
    p->num = no;
    return p;
}

void insert(int no, PList pl)
{
    PList last;
    last = pl;
    while(last->next != NULL)
        last = last->next;
    last->next = create(no);
}

void printPList(PList pl)
{
    PList tmp;
    tmp = pl;
    do{
        printf("%d ",tmp->num);
        tmp = tmp->next;
    }while(tmp!=pl);
}

// 开始数数
PList Josephus(int k,PList header)
{
    PList tmp, prev;
    int i, time, count;

    tmp = header->next;
    count = 2;
    while(tmp->next != header){
        tmp = tmp->next;
        count++;
    }

    time = 0;
    tmp = header;

    while( (count - time++) > 2){
        for(i=1;i<k;i++){
            prev = tmp;
            tmp = tmp->next;
        }
        prev->next = tmp->next;
        free(tmp);
        tmp = prev->next;
    }

    return tmp;
}

int main()
{
    int i;
    PList header, tmp;
    header = create(1);
    for(i=2;i<=41;i++)
        insert(i,header);
    tmp = header;
    while(tmp->next != NULL)
        tmp = tmp->next;
    tmp->next = header; // 循环链表达成

    // 打印
    printPList(header);

    header = Josephus(3, header);

    printf("\nlast two num: ");
    // 打印
    printPList(header);

    return 0;
}


结果:



选择 16 和 31 就能避免哦

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值