2021-10-10

今天记录留的PTA上的第一题
带密码的约瑟夫环
输入人数5,m为密码
带密码的约瑟夫问题:编号为1,2,…,n的n个人按照顺时针方向围坐一圈,每个人有自己的编号(正整数)、姓名和密码(正整数)三个数据项。一开始任选一个正整数(2)作为报数上限值,从第一个人开始顺时针方向自1开始报数,报到m时停止报数。报m 的人出列,将他的密码作为新的m值,从他在顺时针方向的下一个人开始重新报数,如此下去,直到所有人全部出队为止。设计一个程序来求出出队顺序。
输入
5
1,刘三,3
2,李丽,5
3,吴勇,8
4,钱多,2
5,齐民,4
2/最开始的正整数/
输出
2,李丽,5
3,吴勇,8
5,齐民,4
4,钱多,2
1,刘三,3
代码:
#include <stdlib.h>
#include <stdio.h>//输入输出头文件
typedef int ElemType1;//定义新名字
typedef struct node
{
ElemType1 num;//号码
char name[10];//名字
ElemType1 password;//密码
struct node* next;//指针域
}LNode;//结点结构体命名为LNode
typedef struct node* LinkList;//将结构体指针重命名为LinkList方便写,其对象为结构体指针,可以理解为,通过typedef,将struct node *替换为linklist,当我们在使用LinkList L定义变量时,实际上就是在使用 struct node * L定义变量。使得以后想定义指向struct node类型的指针变量时,不需要写struct node * ,只需要使用LinkList,减少了代码的书写。

可理解为:
linklist = struct node *
后续malloc时候,返回值为void型,写法如下:
linklist L;
L = (linklist)malloc(sizeof(linknode));
/

LinkList ListInit()
{
LinkList list;/创建单链表list其头指针也叫list,/
list = (LinkList)malloc(sizeof(LNode));/创建一个结点,list为头结点/
return list;//把链表返回
}
void InsertList(int n, LinkList list)/链表的插入/
{
int i;/用于for循环/
LinkList p = list;/p指针用于移动/
for (i = 0; i < n; i++)
{
scanf("%d,%[^,],%d", &p->num, p->name, &p->password);
p->next =(LinkList)malloc(sizeof(LNode));//生成新结点
if (i == n - 1)
p->next = list;/尾接头/
else
p = p->next;
}
}/将五个人输进去/

![graph TD;
A-->B;
B-->C;](https://img-blog.csdnimg.cn/20211010212214557.jpg?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3FxXzUyOTgzNjUw,size_16,color_FFFFFF,t_70)

void PassGroup(LinkList list, int m, int n)/淘汰人函数/
{
LinkList p = list;/用来移动/
LinkList q;/记录淘汰的人/
int i;
while (n != 0)/只要人数不减为0就一直循环/
{
for (i = 1; i < m; i++)/刚开始m=2/
{
q = p;
p = p->next;
}
m = p->password;/传递下一个m/重要!!!!!
printf("%d,%s,%d\n", p->num, p->name, p->password);/第一个人,李丽/
q->next = p->next;
p = p->next;
n–;/记录人数减少/
}
}
int main()
{
int n, m;
scanf("%d", &n);
if (n < 0)
return 0;
LinkList list;//定义链表
list = ListInit();//初始化
InsertList(n, list);//插入
scanf("%d", &m);
if (m <= 0)
return 0;
PassGroup(list, m, n);//淘汰
return 0;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值