关于约瑟夫问题: C语言程序输入m的值后出现错误,如下图所示。

关于约瑟夫问题: C语言程序输入m的值后出现错误,如下图所示。,第1张

根据你的输入:

1、n = 4,即表示链表中有四个节点;

2、m = 7,执行output()函数时进入以下这段代码,

while(j!=(m==1n+1:m)) \\ 即相当于while(j!=7)

{

t=p;

p=p->next;

j++;

}

明显p指针移动的次数肯定超过了4次,程序会崩掉的,仔细检查下这段代码

#include <stdioh>

#include <conioh>

#define N 300

int main(){

 int hou[N],n,m,i,j,k;

 while(1){

  scanf("%d%d",&n,&m);

  if(n<1)break;

  for(i=0;i<n;++i){

   hou[i]=i+1;

  }

  printf("Out: ");

  k=-1;//从第k位置开始报数

  for(i=0;i<n-1;++i){//循环一次出局一只猴子,共出局n-1只猴子

   for(j=0;j<m;++j){

    do{

     k=(k+1)%n;

    }while(hou[k]==0);//找到第一个非零元素(即还没出局的猴子)报数

   }

   printf("%d ",hou[k]);

   hou[k]=0;//报数到m的猴子出局

  }

  do{

   k=(k+1)%n;

  }while(hou[k]==0);//找到第一个非零元素(即还没出局的猴子)报数

  printf("\nLeave:%d\n",hou[k]);

 }

 printf("\nFinished!\n");

 getch();

 return 0;

}

1、约瑟夫问题:Joseph问题的一种描述是:编号为1、2、……、n的n个人按顺时针方向围坐一圈,每人持有一个密码(正整数)。一开始任选一个正整数作为报数上限值m,从第一个人开始顺时针方向自1开始顺序报数,报到m时停止报数,报m的人出列,将他的密码作为新的m值,从他在顺时针方向的下一个人开始重新从1报数,如此下去,直至所有人全部出列为止。

2、例程:

#include

#include

typedef int ElemType;

typedef struct LNode{

ElemType data;int num;

struct LNode next;

}LNode,LinkList;

void CreateList_L(LinkList L,int n)

{ int i=0;

ElemType e;

LinkList p,q;

L=(LinkList)malloc(sizeof(LNode));

(L)-> next=NULL;(L)-> data=n;

q=L;

while(i

data=e;p-> num=i+1;

p-> next=NULL;

q-> next=p;

q=p;

i++;

}

p-> next=(L)-> next;

}

void PrintList(LinkList L)

{ int i=0;

LinkList p;

p=L-> next;

while(i

data)

{

printf("%5d",p-> data);

p=p-> next;

i++;

}

printf("\n");

}

void Put(LinkList L)

{ int i,m;LinkList p,q;

printf("input a number:\n");

scanf("%d",&m);

q=(L)-> next;

while((L)-> data)

{for(i=0;i

next;

}

printf("%5d",q-> num);

m=q-> data;

p-> next=q-> next;

free(q);

q=p-> next;

(L)-> data=(L)-> data-1;

}

}

void main()

{LinkList L;

int a;

printf("请输入人数:");

scanf("%d",&a);

printf("请输入密码:");

CreateList_L(&L,a);

printf("您输入的数字为:\n");

PrintList(L);

Put(&L);

}

/

基本要求

基本的约瑟夫的描述:

古代某法官要判决N个犯人的死刑,他有一条荒唐的法律,将犯人站成一个圆圈,

从第S个人开始数起,每数到第D个犯人,就拉出来处决,然后再数D个,数到的人再处决,

直到剩下的最后一个可赦免。

发展的约瑟夫的描述:

古代某法官要判决N个犯人的死刑,

但这N个人每人持有一个密码,他有一条荒唐的法律,将犯人站成一个圆圈,

法官先给出一个密码M,从第S个人开始数起,每数到第M个犯人,就拉出来处决,

再根据这个人所持有的密码F,然后再数F个,数到的人再处决,

以此类推直到剩下的最后一个可赦免。

测试数据

数据请自己添加。

/

#include <iostream>

using namespace std;

// 表示一个犯人的结构体

struct Prisoner

{

// 编号

int id;

// 密码

int pass;

// 用于链表的指针

struct Prisoner pre;

struct Prisoner next;

};

class JosephCircle

{

public:

// 基本的约瑟夫构造函数

JosephCircle(int N,int S,int D);

// 发展的约瑟夫构造函数

JosephCircle(int N,int S,int M,int password[]);

// 输出约瑟夫环

void print();

// 开始处决犯人

void start();

private:

// 约瑟夫环的头指针

struct Prisoner head;

// 第一个被处决的犯人的节点指针

struct Prisoner firstPunishedPrision;

};

JosephCircle::JosephCircle(int N,int S,int D)

{

struct Prisoner p , pr;

// 约瑟夫环的头指针初始化为空

this->head = NULL;

// 构造一个由 N 个犯人组成的约瑟夫环

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

{

// 当前添加的犯人是第一个犯人,要特殊处理一下

if(this->head == NULL)

{

// 新增一个犯人

p = new struct Prisoner();

// 犯人编号

p -> id = i;

// 犯人密码

p -> pass = D;

// 紧挨着的下一个犯人(因为是环状的,每个人都会有紧挨着的其他犯人)

p -> pre = p;

p -> next = p;

// 约瑟夫环的头指针

this->head = pr = p;

}

else

{

p = new struct Prisoner();

p -> id = i;

p -> pass = D;

p -> pre = pr;

p -> next = pr->next;

pr -> next -> pre = p;

pr -> next = p;

pr = p;

}

}

// 寻找约瑟夫环里面第一个被处决的犯人的节点指针

firstPunishedPrision = head;

for(int i=2;i<=(S+D-1);i++)

{

this->firstPunishedPrision = this->firstPunishedPrision -> next;

}

}

JosephCircle::JosephCircle(int N,int S,int M,int password[])

{

struct Prisoner p , pr;

// 约瑟夫环的头指针初始化为空

this->head = NULL;

// 构造一个由 N 个犯人组成的约瑟夫环

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

{

// 当前添加的犯人是第一个犯人,要特殊处理一下

if(this->head == NULL)

{

// 新增一个犯人

p = new struct Prisoner();

// 犯人编号

p -> id = i;

// 犯人密码

p -> pass = password[i-1];

// 紧挨着的下一个犯人(因为是环状的,每个人都会有紧挨着的其他犯人)

p -> pre = p;

p -> next = p;

// 约瑟夫环的头指针

this->head = pr = p;

}

else

{

p = new struct Prisoner();

p -> id = i;

p -> pass = password[i-1];

p -> pre = pr;

p -> next = pr->next;

pr -> next -> pre = p;

pr -> next = p;

pr = p;

}

}

// 寻找约瑟夫环里面第一个被处决的犯人的节点指针

firstPunishedPrision = head;

for(int i=2;i<=(S+M-1);i++)

{

this->firstPunishedPrision = this->firstPunishedPrision -> next;

}

}

// 输出约瑟夫环

void JosephCircle::print()

{

struct Prisoner p = this->head;

if(p != NULL)

{

do

{

cout << "[编号:" << p->id << ",密码:" << p->pass << "]" ;

if(p->next != this->head)

{

cout<<" -> ";

}

p = p->next;

}while(p != this->head);

}

cout << endl << endl;

}

// 开始处决犯人

void JosephCircle::start()

{

struct Prisoner p = this->firstPunishedPrision,pr,q;

int counter = 1;

/

因为约瑟夫环是一个循环链表(也就是一个圈),

当 p->next != p 的时候,说明圈里面还有多余一个的节点(犯人),

继续数数并处决犯人

/

while(p->next != p)

{

// q 向当前被处决的犯人

q = p;

// 从约瑟夫环里面删除被处决掉的犯人

q -> pre -> next = q -> next;

q -> next -> pre = q -> pre;

p = p -> next;

// 输出被处决的犯人的信息

cout << "第 "<< (counter++) << " 个被处决的犯人编号:" << q->id <<endl;

// 寻找下一个将要处决的犯人

for(int i=1;i<=(q->pass-1);i++)

{

p = p->next;

}

// 释放内存(被处决掉的犯人)。

free(q);

}

// 输出被赦免的犯人的信息

cout << "被赦免的犯人的编号:" << p->id << endl << endl;;

}

int main(int argc, char argv[])

{

// 基本的约瑟夫环: JosephCircle(int N,int S,int D);

JosephCircle j1 = JosephCircle(3,1,2);

j1print();

j1start();

// 发展的约瑟夫环: JosephCircle(int N,int S,int M,int password[]);

int pass[]={1,5,3};

JosephCircle j2 = JosephCircle(3,1,2,pass);

j2print();

j2start();

return 0;

}

花了一个晚上写出来的,希望对你有帮助

using System;

using SystemCollectionsGeneric;

using SystemLinq;

using SystemText;

namespace Task5_约瑟夫问题__退圈游戏

{

class Program

{

static void Main(string[] args)

{

ConsoleWrite("输入参加游戏的人数:");

int Person_numb = ConvertToInt32(ConsoleReadLine());

ConsoleWrite("输入“不幸数字”:");

int UnluckyNumber = ConvertToInt32(ConsoleReadLine());

int Winner = Play(Person_numb, UnluckyNumber);

ConsoleWriteLine("\n将游戏者从“1”到“{0}”依次进行编号后每数到“{2}”的倍数的玩家被淘汰!\n\n经过春哥精密的计算,最终的胜利者是编号为“{1}”的游戏者!",Person_numb ,Winner,UnluckyNumber );

ConsoleReadKey ();

}

static int Play(int Person_numb, int UnluckeyNumber)

{

int Winner = 0;//用来存放最后胜利者的编号

int Unlucky_count = 0;//从0开始,每数到不行数字的倍数再从头开始数

int[] Persons = new int[Person_numb];//对其进行赋值1或0来检查该游戏者是否已经被淘汰

int NewPerson_numb = Person_numb;//更新还剩下的没有被淘汰的人数

for (int i = 0; i < Person_numb; i++)

{

Persons[i] = 1;//所有人的初始值为1,表示尚未被淘汰,0表示已经被淘汰

}

for (int j=0; NewPerson_numb>1/只要未被淘汰的人数大于1,就继续数下去/; j=j%Person_numb/ 用余数法来解决围成一圈后人数的循环问题/)

{

if (Persons[j] == 0)//如果该游戏者已被淘汰,则不做处理,直接再数到下一个人

{

j++;

}

else//数到未被淘汰的游戏者

{

Unlucky_count++;//验证数字加1

j++;//继续数下一个

}

if (Unlucky_count == UnluckeyNumber)//验证是否数到一个不幸数字

{

Persons[j-1] = 0;//是不幸数字的倍数,则将此人标记为淘汰

NewPerson_numb = NewPerson_numb - 1;//更新还剩下的没有被淘汰的人数

Unlucky_count = 0; //再从头开始数

}

}

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

{

if (Persons[i -1] == 1)//检测最后一个未被淘汰的游戏者的编号

{

Winner = i;

}

}

return Winner;//返回编号

}

}

}

以上就是关于关于约瑟夫问题: C语言程序输入m的值后出现错误,如下图所示。全部的内容,包括:关于约瑟夫问题: C语言程序输入m的值后出现错误,如下图所示。、c语言 约瑟夫问题 下面给出具体问题和我编的程序,求大神指导。、约瑟夫问题c语言等相关内容解答,如果想了解更多相关内容,可以关注我们,你们的支持是我们更新的动力!

欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/zz/9743291.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2023-05-01
下一篇 2023-05-01

发表评论

登录后才能评论

评论列表(0条)

保存