[链表]九度OJ 题目1188:约瑟夫环

本文探讨了经典的约瑟夫环问题,并提供了一种使用循环链表进行求解的方法。通过不断移除符合条件的节点来模拟游戏过程,最终输出所有被移除节点的顺序。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

题目描述:

N个人围成一圈顺序编号,从1号开始按1、2、3......顺序报数,报p者退出圈外,其余的人再从1、2、3开始报数,报p的人再退出圈外,以此类推。
请按退出顺序输出每个退出人的原序号。

输入:

包括一个整数N(1<=N<=3000)及一个整数p。

输出:

测试数据可能有多组,对于每一组数据,
按退出顺序输出每个退出人的原序号。

样例输入:

7 3

样例输出:

3 6 2 7 5 1 4

来源:

2003-2005年华中科技大学计算机研究生机试真题

答疑:

解题遇到问题?分享解题心得?讨论本题请访问:http://t.jobdu.com/thread-7911-1-1.html


代码(超出内存限制)

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

typedef struct Node
{
    int people;
    struct Node *next;
}Node;

typedef Node *CycleList;

CycleList CreatList(int n);
void RingKill(int n, int t);

int main()
{
    int n,t;
    while(scanf("%d %d", &n, &t))
    {
        RingKill(n, t);
    }
    return 0;
} 

CycleList CreatCL(int n)
{
    int i;
    CycleList L, p, r;
    r = L = (CycleList)malloc(sizeof(Node)); //头节点 
    for(i = 1; i <= n; i ++)
    {
        p = (CycleList)malloc(sizeof(Node));
        r -> next = p;
        p -> people = i;
        p -> next = NULL;
        r = p;
    }
    p -> next = L -> next; //循环链表最后一个节点指向第一个节点
    return L; 
}

void RingKill(int n, int t)
{
    CycleList L = CreatCL(n);
    CycleList p = L, front = L;
    if(t == 1) //t = 1 相当于一个一个打印
    {
        for(int j = 0; j < n - 1; j ++)
        {
            p = p -> next;
            printf("%d ", p -> people); 
        }
        printf("%d\n", p -> next -> people); 
    }
    else
    {
        while(front -> next != front)
        {
            for(int i = 0; i < t; i ++)
                p = p -> next;
            for(int i = 0; i < t - 1; i ++)
                front = front -> next;
            printf("%d ", p -> people);
            front -> next = p -> next; //删除p节点 
        }
        printf("%d\n", front -> people);
    }
}

结果提交了这么多遍什么错误都遇到了〒_〒

解决方案

free( ) -> Memory Limit Exceed
while(scanf(“%d%d”, &n, &t) != EOF) -> Output Limit Exceed

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

typedef struct Node
{
    int people;
    struct Node *next;
}Node, *CycleList;

CycleList CreatList(int n);
void RingKill(int n, int t);

int main()
{
    int n,t;
    while(scanf("%d%d", &n, &t) != EOF)
        RingKill(n, t);
    return 0;
} 

CycleList CreatCL(int n)
{
    int i;
    CycleList head, p, r;
    r = head = (CycleList)malloc(sizeof(Node)); //头节点 
    //L->people=0;
    for(i = 1; i <= n; i ++)
    {
        p = (CycleList)malloc(sizeof(Node));
        r -> next = p;
        p -> people = i;
        p -> next = NULL;
        r = p;
    }
    p -> next = head -> next; //循环链表最后一个节点指向第一个节点
    free(head);
    return p->next; //返回第一个节点 
}

void RingKill(int n, int t)
{
    CycleList L = CreatCL(n);
    CycleList p = L, front = L;
    while(front->next!=L)front=front->next; //先让front指向最后一个节点 
    while(front -> next != front)
    {
        for(int i = 1; i < t; i ++)
        {
            front = p;
            p = p -> next;
        }
        printf("%d ", p -> people);
        front -> next = p -> next; //删除p节点 
        free(p);
        p=front->next;
    }
    printf("%d\n", front -> people);
    free(front);
}

Accepted!

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值