约瑟夫环c语言循环指针,约瑟夫环(c语言)(双循环、单循环)

/*题目:

耶稣又15个门徒,其中有一个时出卖耶稣的叛徒,请用排除法找出这位门徒:15人围坐一圈,从第一个开始报号:1,2,3,1,2,3.。。凡是报到“3”的退出圈子,最后留在圈子内的就是叛徒。找出他原来的序号。、

答案:第5个(后面有优化改进方法)

分析:

1、 先说思路,从第一个报数,引入一个计数count,报到3(就是count加到3)的标记位好人,并且让他下次循环不报数。而且count赋值0,继续报数,以此循环。因为报到第十五个人,需要继续从第1个再报数,因此外围还要有个循环,外围第循环用好人数来控制,当好人到15个的时候停止报数,这时最后一个,也就是第十五个好人就是叛徒,因此在标记好人的时候,加上一个pantu的记录,用来记录这个人的序号。最后一次记录的序号就是叛徒。

2、 一开始定义了个二维数组,想的是一个定义序号,一个定义是否是好人(0,1),后来想了想没必要,序列号直接下标就可以了。

*/

#import

int main()

{

int people[15] = {0};  // 定义数组15个人,下标+1就代表序号。元素0代表不知道是否是好人。当后面改为1的代表是好人。

int count = 0;         // 用来记报的数,循环时从1开始,数到3就归0.

int haoren = 0;        // 好人个数,报到3,好人就加一个

int pantu = 0;         // 叛徒,最后一个好人就是叛徒

for (; haoren <= 14;)   // 外循环,直到出现15个好人时停止循环

{

for (int i = 0; i <= 14; i++)  // 15个人从头报数

{

if (people[i] == 0)     // 如果不确定是好人,就报数

{

count ++;           // 只要有人报数就+1

if (count == 3)     // 报到3时,进行下面到操作

{

count = 0;      // 报到计数归0,后面到人继续从1报

people[i] = 1;  // 报3的人标记为好人,后面不再参与报数

haoren ++;      // 好人数加1

pantu = i+1;    // 叛徒暂时标记为最后这个报数的人(一开始没有+1,忘了下标是从0开始的)

}

}

}

}

printf("叛徒的序号是%d\n",pantu); // 打印出叛徒的序号,打印结果为5

return 0;

}

/*

我把代码又改进了一下,双循环改为一个循环。(建议先浏览第十题后再浏览本页代码)

*/

#import

int main()

{

int people[15] = {0};

int count = 0;

int haoren = 0;

int pantu = 0;

int i = 0;                          // 这一句要写到外面了。不能每次循环都从0开始。

for (; haoren <= 14;i ++ )      // 从此处改动,循环一直继续,直到出现第十五个好人结束。

{

if (people[i] == 0)

{

count ++;

if (count == 3)

{

count = 0;

people[i] = 1;

haoren ++;

pantu = i+1;

}

}

if (i == 14)                 // 报数到第十五个人,返回头再开始报数

{

i = -1;

}

}

printf("叛徒的序号是%d\n",pantu);

return 0;

}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
循环队列可以用来解决约瑟夫环问题。约瑟夫环是一个数学问题,描述了一个编号为1到n的人围成一圈,从第一个人开始报数,报到m的人出列,然后从下一个人开始重新报数,直到所有人都出列为止。循环队列可以模拟这个过程。 下面是一个使用C语言实现循环队列解决约瑟夫环问题的例子: ```c #include <stdio.h> #include <stdlib.h> #define MAX_SIZE 100 typedef struct { int data[MAX_SIZE]; int front; int rear; } Queue; void initQueue(Queue *q) { q->front = q->rear = 0; } int isEmpty(Queue *q) { return q->front == q->rear; } int isFull(Queue *q) { return (q->rear + 1) % MAX_SIZE == q->front; } void enqueue(Queue *q, int value) { if (isFull(q)) { printf("Queue is full.\n"); return; } q->data[q->rear] = value; q->rear = (q->rear + 1) % MAX_SIZE; } int dequeue(Queue *q) { if (isEmpty(q)) { printf("Queue is empty.\n"); return -1; } int value = q->data[q->front]; q->front = (q->front + 1) % MAX_SIZE; return value; } int josephus(int n, int m) { Queue q; initQueue(&q); for (int i = 1; i <= n; i++) { enqueue(&q, i); } while (!isEmpty(&q)) { for (int i = 1; i < m; i++) { int value = dequeue(&q); enqueue(&q, value); } int eliminated = dequeue(&q); printf("%d ", eliminated); } printf("\n"); } int main() { int n, m; printf("Enter the number of people: "); scanf("%d", &n); printf("Enter the count number: "); scanf("%d", &m); josephus(n, m); return 0; } ``` 这段代码中,我们使用一个循环队列来模拟约瑟夫环的过程。首先,我们定义了一个Queue结构体,包含一个数组data用来存储队列元素,以及front和rear两个指针分别指向队列的头部和尾部。然后,我们实现了一些基本的队列操作函数,包括初始化队列、判断队列是否为空、判断队列是否已满、入队和出队操作。接下来,我们定义了一个josephus函数,该函数接受两个参数n和m,分别表示人数和报数的数字。在josephus函数中,我们首先初始化一个循环队列,并将1到n的数字依次入队。然后,我们开始模拟报数的过程,每次出队一个数字,如果还没有报到m,则将该数字重新入队,直到队列为空为止。最后,我们在主函数中读取用户输入的人数和报数的数字,并调用josephus函数进行模拟。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值