约瑟夫生死问题

法一:


#include <stdio.h>

#include<malloc.h>

#define ERROR -1

#define MAXSIZE 100



typedef int ElementType;



//typedef struct QNode *PtrToLNode;

typedef struct QNode *Queue;

struct QNode

{

	ElementType *Data;

	int Front,Rear;  //定义队头,队尾

	int MaxSize;      //定义最大空间

};

//typedef PtrToLNode Queue;
//建队列
Queue CreateQueue (int MaxSize)

{

	Queue Q=(Queue)malloc(sizeof(struct QNode));

	Q->Data=(ElementType *)malloc(MaxSize *sizeof(ElementType));

	Q->Front=Q->Rear=0;  //对队头队尾进行初始定位

	Q->MaxSize=MaxSize;  //对最大空间进行初始化

	return Q;

}
//是不是满
bool IsFull(Queue Q)

{

	return (Q->Rear+1)%Q->MaxSize==Q->Front;

}
//是不是空
bool IsEmpty(Queue Q)

{

	return Q->Front==Q->Rear;

}
//插入
bool AddQ(Queue Q,ElementType X)

{

	if(IsFull(Q))

	{

		printf("队列满!");

		return false;

	}

	else

	{

		Q->Rear=(Q->Rear+1)%Q->MaxSize;

		Q->Data[Q->Rear]=X;

		return	true;

	}

}
//弹出
ElementType DeleteQ(Queue Q)

{

	if(IsEmpty(Q))

	{

		printf("队列空!");

		return ERROR;

	}

	else

	{
		
		Q->Front=(Q->Front+1)%Q->MaxSize;//修改队头位置

		return Q->Data[Q->Front];	//返回队头元素

	}

}

//显示
void DispQueue(Queue Q)

{
	int i;
	//多于
	if(IsEmpty(Q)) {
		printf("队列空!");
		return ;
	}
	if(Q->Front<Q->Rear) {
		for (i=Q->Front+1; i<=Q->Rear; i++)
			printf("%d ",Q->Data[i]);
		printf("\n");
	} else {
		for (i=Q->Front+1; i<=Q->Rear;)

		{
			printf("%d ",Q->Data[i]);

			i=(i+1)	%Q->MaxSize;
		}
		printf("\n");
	}
}



void yuesefu(Queue Q,int players,int number);



int main()

{

	int Maxsize=100;

	Queue Q=CreateQueue(Maxsize);

	int i=1,j=1,choice,val,players,number;

	int count=1,e;

	char a;

	while(i)

	{

		printf("\n\n\n\n");

		printf("\n\t\t                队列子系统\n");

		printf("\n\t\t************************************");

		printf("\n\t\t*         1------入    队          *");

		printf("\n\t\t*         2------出    队          *");

		printf("\n\t\t*         3------显示队列中元素    *");

		printf("\n\t\t*         4------约瑟夫生死问题    *");

		printf("\n\t\t*         0------返    回          *");

		printf("\n\t\t************************************");

		printf("\n\t\t请选择菜单号(0--5):");
		

		choice=getchar();
		
		getchar();

		switch(choice)

		{

			case '1':

				j=1;

				while(j)

				{

					printf("\t\t请键入一个整数(按回车输入下一个,输入'0'结束):");

					scanf("%d",&val);
					getchar();

					if(val!=0)

						AddQ(Q,val);

					else

						j=0;

				}
				break;

			case '2':
				
				printf("\t\t出队元素为:%6d\n",DeleteQ(Q));

				break;

			case '3':

				DispQueue(Q);

				break;

			case '4':

				printf("\n\t\t请输入总人数:");

				scanf("%d",&players);

				printf("\n\t\t请输入报数:");

				scanf("%d",&number);

				yuesefu(Q,players,number);
				getchar();
				break;

			case '0':

				i=0;

				break;

		}

	}

	return 0;

}



void yuesefu(Queue Q,int players,int number)

{
	//max=players+1
	//这里就不是填空啦,按照分析的思路要自己写代码了
	int sum=players+1,data;
	int k=0;
	for(int i=1; i<=players; i++)
		AddQ(Q,i);
		while(players!=1){
			for(int i=1;i<number;i++){
				DeleteQ(Q);
				AddQ(Q,Q->Data[Q->Front]);
			}
			DeleteQ(Q);
			players--;
		}
	printf("幸存者是%d",Q->Data[Q->Rear]);
}


 

 

 

 

 

法二:

#include <stdio.h>



#include<malloc.h>



#define ERROR -1



#define MAXSIZE 100







typedef int ElementType;







//typedef struct QNode *PtrToLNode;



typedef struct QNode *Queue;



struct QNode



{



	ElementType *Data;



	int Front,Rear;  //定义队头,队尾



	int MaxSize;      //定义最大空间



};



//typedef PtrToLNode Queue;

//建队列

Queue CreateQueue (int MaxSize)



{



	Queue Q=(Queue)malloc(sizeof(struct QNode));



	Q->Data=(ElementType *)malloc(MaxSize *sizeof(ElementType));



	Q->Front=Q->Rear=0;  //对队头队尾进行初始定位



	Q->MaxSize=MaxSize;  //对最大空间进行初始化



	return Q;



}

//是不是满

bool IsFull(Queue Q)



{



	return (Q->Rear+1)%Q->MaxSize==Q->Front;



}

//是不是空

bool IsEmpty(Queue Q)



{



	return Q->Front==Q->Rear;



}

//插入

bool AddQ(Queue Q,ElementType X)



{



	if(IsFull(Q))



	{



		printf("队列满!");



		return false;



	}



	else



	{



		Q->Rear=(Q->Rear+1)%Q->MaxSize;



		Q->Data[Q->Rear]=X;



		return	true;



	}



}

//弹出

ElementType DeleteQ(Queue Q)



{



	if(IsEmpty(Q))



	{



		printf("队列空!");



		return ERROR;



	}



	else



	{

		

		Q->Front=(Q->Front+1)%Q->MaxSize;//修改队头位置



		return Q->Data[Q->Front];	//返回队头元素



	}



}



//显示

void DispQueue(Queue Q)



{

	int i;

	//多于

	if(IsEmpty(Q)) {

		printf("队列空!");

		return ;

	}

	if(Q->Front<Q->Rear) {

		for (i=Q->Front+1; i<=Q->Rear; i++)

			printf("%d ",Q->Data[i]);

		printf("\n");

	} else {

		for (i=Q->Front+1; i<=Q->Rear;)



		{

			printf("%d ",Q->Data[i]);



			i=(i+1)	%Q->MaxSize;

		}

		printf("\n");

	}

}







void yuesefu(Queue Q,int players,int number);







int main()



{



	int Maxsize=100;



	Queue Q=CreateQueue(Maxsize);



	int i=1,j=1,choice,val,players,number;



	int count=1,e;



	char a;



	while(i)



	{



		printf("\n\n\n\n");



		printf("\n\t\t                队列子系统\n");



		printf("\n\t\t************************************");



		printf("\n\t\t*         1------入    队          *");



		printf("\n\t\t*         2------出    队          *");



		printf("\n\t\t*         3------显示队列中元素    *");



		printf("\n\t\t*         4------约瑟夫生死问题    *");



		printf("\n\t\t*         0------返    回          *");



		printf("\n\t\t************************************");



		printf("\n\t\t请选择菜单号(0--5):");

		



		choice=getchar();

		

		getchar();



		switch(choice)



		{



			case '1':



				j=1;



				while(j)



				{



					printf("\t\t请键入一个整数(按回车输入下一个,输入'0'结束):");



					scanf("%d",&val);

					getchar();



					if(val!=0)



						AddQ(Q,val);



					else



						j=0;



				}

				break;



			case '2':

				

				printf("\t\t出队元素为:%6d\n",DeleteQ(Q));



				break;



			case '3':



				DispQueue(Q);



				break;



			case '4':



				printf("\n\t\t请输入总人数:");



				scanf("%d",&players);



				printf("\n\t\t请输入报数:");



				scanf("%d",&number);



				yuesefu(Q,players,number);

				getchar();

				break;



			case '0':



				i=0;



				break;



		}



	}



	return 0;



}







void yuesefu(Queue Q,int players,int number)



{

	//max=players+1

	//这里就不是填空啦,按照分析的思路要自己写代码了

	int sum=players+1,data;

	int k=0;

	for(int i=1; i<=players; i++)

		AddQ(Q,i);

	Q->Data[0]=0;

	while(players!=1) {

		Q->Front=(Q->Front+1)%sum;

		if(Q->Data[Q->Front]!=0) {

			k++;

			if(k==number) {

				Q->Data[Q->Front]=0;

				players--;

				k=0;

			}

		}

	}

	for(int i=1; i<=sum-1; i++) {

		if(Q->Data[i]!=0) 

		data=Q->Data[i];	

	}

	printf("幸存者是%d",data);

}

 

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
以下是一种C语言的解: ```c #include <stdio.h> #include <stdlib.h> // 队列结构体 typedef struct Node { int data; struct Node *next; } Node; typedef struct Queue { Node *front, *rear; } Queue; // 初始化队列 void init(Queue *q) { q->front = q->rear = NULL; } // 判断队列是否为空 int is_empty(Queue *q) { return q->front == NULL; } // 入队 void enqueue(Queue *q, int val) { Node *new_node = (Node*)malloc(sizeof(Node)); new_node->data = val; new_node->next = NULL; if (is_empty(q)) { q->front = q->rear = new_node; } else { q->rear->next = new_node; q->rear = new_node; } } // 出队 int dequeue(Queue *q) { if (is_empty(q)) { printf("Queue is empty!\n"); exit(1); } int val = q->front->data; Node *temp = q->front; q->front = q->front->next; free(temp); return val; } // 约瑟夫问题 int josephus(int n, int m) { Queue q; init(&q); for (int i = 1; i <= n; i++) { enqueue(&q, i); } int count = 0; while (!is_empty(&q)) { int val = dequeue(&q); count++; if (count % m == 0) { if (is_empty(&q)) { return val; } } else { enqueue(&q, val); } } return -1; } int main() { int n, m; scanf("%d%d", &n, &m); printf("%d\n", josephus(n, m)); return 0; } ``` 在本解中,我们使用了队列来模拟约瑟夫问题的过程。我们首先将所有人的编号依次入队,然后不断出队,每次出队时判断是否到了第m个人。如果是第m个人,我们就将他踢出队列,否则就将他重新入队。当队列中只剩下一个人时,他就是最后留下的人,我们将他的编号返回即可。 注意,我们在判断是否是第m个人时,要特别注意队列是否已经为空的情况。如果队列已经为空,那么当前出队的人就是最后一个人了,我们应该返回他的编号。否则,我们就将当前出队的人重新入队。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

小丞啊

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值