NOJ 1033 约瑟夫问题

2016.12.27

【问题描述】
描述
设有N名同学手拉手围成一圈,自1、2、3、……开始编号,现从1号开始连续数数,每数到M将此同学从圈中拉走, 求最后被拉走的同学的编号

输入
两个正整数,分别为N和M,0 < N <= 100, 0 < M < 65535
输出
一个正整数,为最后被拉走的同学的编号,最后输出回车

输入样例
5 3
输出样例
4

【解题思路】
链表实现

【代码实现】

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

int n, m, cnt, cntm;
struct node
{
    int num;
    struct node * next;
};

struct node * create();
void del(struct node *);

int main(void)
{
    int i;
    struct node * head;
    struct node * current, * tt;

    scanf("%d%d", &n, &m);

    cntm = 0;
    cnt = n;
    head = create();

    current = head;
    while (cnt > 1)
    {
        cntm++;
        if (cntm == m)
        {
            tt = current->next;
            cnt--;
            cntm = 0;
            del(current);
            current = tt;
        }
        else
            current = current->next;
    }

    printf("%d\n", current->num);
    free(current);

    return 0;
}

struct node * create()
{   
    int i;
    struct node * head = NULL;
    struct node * prev, * current;

    for (i = 1; i <= n; ++i)
    {
        current = (struct node *) malloc(sizeof(struct node));
        if (head == NULL)
            head = current;
        else
            prev->next = current;
        current->next = head;
        current->num = i;
        prev = current;
    }

    return head;    
}

void del(struct node * c)
{
    int i;
    struct node * t;

    for (i = 1; i <= cnt; ++i)
        c = c->next;
    t = c->next->next;
    free(c->next);
    c->next = t;
}

【心得体会】
掌握链表的基本使用

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值