根据你的输入:
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语言等相关内容解答,如果想了解更多相关内容,可以关注我们,你们的支持是我们更新的动力!
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)