PTA练习之约瑟夫问题

Josephus

问题描述:编号为1,2,…,n的n个人按顺时针方向围坐在一张圆桌周围,每人持有一个密码(正整数)。一开始任选一个正整数m作为报数上限值,从第一个人开始按顺时针方向自1开始报数,报到m时停止报数,报m的那个人出列,将他的密码作为新的m值,从他顺时针方向的下一个人开始重新从1报数,数到m的那个人又出列;如此下去,直至圆桌周围的人全部出列为止。要求按出列顺序输出n个人的编号。

输入格式:
第一行输入两个整数,依次表示人数n和初始化密码m,以空格间隔。 第二行依次输入n个整数,分别表示n个人的密码,以空格间隔。

输出格式:
按出列次序输出每个人的编号,以空格间隔。

输入样例:
在这里给出一组输入。例如:
7 20
3 1 7 2 4 8 4

输出样例:
在这里给出相应的输出。例如:
6 1 4 7 2 3 5

/思路:循环链表,循环移动结点,找到后删除结点,继续寻找,直至所有结点都被找过/

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

typedef struct node
{
    int num, password;
    struct node *next;
}*Linklist;
Linklist H,r,s;
//创建循环链表
void Creat_Tlinklist(int n)
{
    H = (Linklist)malloc(sizeof(Linklist));
	r = H;
    int i;
    int x;
    for (i = 1; i < n;i++)
    {
        s = (Linklist)malloc(sizeof(Linklist));
        r->next = s;
        r = s;
    }
    r->next = H;
    s = H;
}

void input_Linklist(int n)
{
	int x;
	for(int i=1;i<=n;i++)
	{
		scanf("%d",&x);
		s->password = x;
		s->num = i;
		s=s->next;
	}
	s = r;
}
//输出并出列
void Output_Linklist(int n,int m)
{
    for (int i = 1; i <= n;i++)
    {
        for (int j = 1; j <m;j++)
            s = s->next;//找到结点
        r = s->next;
        m = r->password;
        printf("%d ", r->num);
        s->next = r->next;
        free(r);
    }
}

//主函数
int main()
{
    int n, m;
    scanf("%d %d", &n, &m);
    Creat_Tlinklist(n);
    input_Linklist(n);
    Output_Linklist(n, m);
    return 0;
}

问题二
编号为1,2,…,n的n个人按顺时针方向围坐在一张圆桌周围。给定一个正整数m≤n,从第一个人开始按顺时针方向自1开始报数,每报到m时就让其出列,从 他顺时针方向的下一个人开始重新从1报数,数到m的那个人又出列。如此下去,直至圆桌周围的人全部出列为止。每个人的出列次序定义了整数1,2,3,…,n的一个排列。这个 排列称为一个(n,m)Josephus排列。例如:(7,3)Josephus排列为3,6,2,7,5,1,4。

输入格式:
输入两个整数,人数n和密码m,以空格间隔。

输出格式:
按出列次序输出每个人的编号,以空格间隔。

输入样例:
在这里给出一组输入。例如:
7 3

输出样例:
在这里给出相应的输出。例如:
3 6 2 7 5 1 4
/思路:和上题一样不过这次不需要提供密码,也就是循环一致,其实我们把上题中所有有关密码的操作全部去掉就可以了/

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

typedef struct node
{
    int num;
    struct node *next;
}*Linklist;
Linklist H,r,s;
//创建循环链表
void Creat_Tlinklist(int n)
{
    H = (Linklist)malloc(sizeof(Linklist));
	r = H;
    int i;
    for (i = 1; i < n;i++)
    {
        s = (Linklist)malloc(sizeof(Linklist));
        r->next = s;
        r = s;
    }
    r->next = H;
    s = H;
}

void input_Linklist(int n)
{
	for(int i=1;i<=n;i++)
	{
		s->num = i;
		s=s->next;
	}
	s = r;
}
//输出并出列
void Output_Linklist(int n,int m)
{
    for (int i = 1; i <= n;i++)
    {
        for (int j = 1; j <m;j++)
            s = s->next;//找到第i-1个结点
        r = s->next;
        printf("%d ", r->num);
        s->next = r->next;
        free(r);
    }
}

//主函数
int main()
{
    int n, m;
    scanf("%d %d", &n, &m);
    Creat_Tlinklist(n);
    input_Linklist(n);
    Output_Linklist(n, m);
    return 0;
}

以上代码仅供参考,有问题希望大佬指正!!!

<think>嗯,用户想要找关于C语言的数据结构和算法的练习题集。首先,我需要确认用户的具体需求。他们可能是在学习数据结构与算法,需要用C语言来练习,可能是学生或者刚入门的程序员。用户提到了参考内容中的数据结构自测题,所以可能希望有类似的资源。 接下来,我应该考虑推荐哪些资源。常见的经典书籍比如《数据结构与算法分析:C语言描述》和《算法导论》都有练习题,但需要确认是否有C语言版本的题目。另外,在线平台如LeetCode、牛客网、PTA等提供大量编程题,可以用C语言解答,这些适合实践练习。 然后,用户可能需要不同类型的题目,比如基础概念题、编程实现题、算法设计题和应用题。例如,链表、栈、队列的操作,排序和搜索算法的实现,树和图的遍历等。同时,应用题如迷宫求解、哈夫曼编码等可以加深理解。 还要注意推荐资源时,需要涵盖书籍、在线平台和开源项目,这样用户有多个选择。比如推荐书籍时,要给出作者和特点,说明为什么适合他们。在线平台要给出链接和特点,比如LeetCode适合面试准备,PTA有中文题目等。 另外,用户可能对如何有效使用这些资源有疑问,所以给出学习建议会更好,比如分阶段练习,结合理论,参与讨论等。这样帮助用户制定学习计划,提高效率。 最后,生成相关问题时要围绕推荐的资源、练习法、不同数据结构的具体题目以及如何检验学习效果。这样用户可以有后续的问题继续探索。</think>### 推荐C语言数据结构与算法练习题集 #### 一、经典教材配套习题 1. **《数据结构(C语言版)》- 严蔚敏** - 包含线性表、树、图等章节的算法实现题 - 重点题目:单链表逆置、二叉树遍历的非递归实现[^1] - 配套习题解析书籍《数据结构题集(C语言版)》 2. **《数据结构与算法分析:C语言描述》- Mark Allen Weiss** - 每章包含渐进复杂度分析、算法设计应用题 - 典型习题:AVL树旋转操作、哈希表冲突解决实现 #### 二、在线编程平台 | 平台名称 | 特点 | 链接 | |----------------|-----------------------------------|------------------------| | LeetCode | 800+数据结构相关题目,支持C语言 | [leetcode.cn](https://leetcode.cn/) | | 牛客网 | 专项训练+企业真题 | [nowcoder.com](https://www.nowcoder.com) | | 浙江大学PTA | 《数据结构》MOOC配套题库 | [pintia.cn](https://pintia.cn) | #### 三、开源项目实践 ```c // 示例:二叉树节点定义 typedef struct TreeNode { int data; struct TreeNode *left; struct TreeNode *right; } TreeNode; // 先序遍历实现 void preorderTraversal(TreeNode *root) { if (root == NULL) return; printf("%d ", root->data); preorderTraversal(root->left); preorderTraversal(root->right); } ``` #### 四、题目类型建议 1. **基础概念题** - 时间复杂度计算:分析循环嵌套结构的复杂度 - 存储结构对比:顺序表 vs 链表的应用场景 2. **编程实现题** - 链表:多项式相加、约瑟夫问题 - 图论:Dijkstra算法实现、拓扑排序 3. **算法设计题** - 动态规划:最长公共子序列C实现 - 分治策略:归并排序的非递归版本 #### 五、学习建议 1. 分阶段练习:从线性结构过渡到树形结构,最后攻克图算法 2. 结合理论:在实现算法时同步推导数学证明,例如快速排序的平均时间复杂度$O(n \log n)$ 3. 参与讨论:在Stack Overflow等平台查看相关问题的C语言实现
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值