C语言编程求解约瑟夫问题

C语言编程求解约瑟夫问题,第1张

约瑟夫环的问题,我给你一个,程序首先输入小孩子个数,然后输入W

首先输出每个小孩子的编号,然后输出出列的数序,最后输出留下的小孩的编号

#include<stdioh>

int Josephus(int Child,int n,int m);

void main()

{

int allChild,j,k,l;

scanf("%d%d",&j,&k);

//cin>>j>>k;

if((allChild= new int[j])!=NULL)

{

for(l=0;l<j;l++)

{

printf("%d,",l+1);

//cout<<l+1<<",";

allChild[l]=l+1;

}

printf("\n");

//cout<<endl;

printf("%d",Josephus(allChild,j,k));

//cout<<Josephus(allChild,j,k);

}

}

int Josephus(int Child,int n,int m)

{

int i=-1,j=0,k=1;

while(1)

{

for(j=0;j<m;)

{

i=(i+1)%n;

if(Child[i]!=-1)

j++;

}

if(k==n)

break;

//cout<<Child[i]<<",";

printf("%d,",Child[i]);

Child[i]=-1;

k=k+1;

}

printf("\n");

//cout<<endl;

return(Child[i]);

}

package 约瑟夫环;

import javautilLinkedList;

import javautilList;

/

约瑟夫环问题的一种描述是:编号为123……n的n个人按顺时针方向围坐一圈 ,每人手持一个密码(正整数),

开始任意选一个整数作为报数上限值,从第一个人开始顺时针自1开始顺序报数,报到m时停止报数。报m的人出列,

将他的密码作为新的m值,从他顺时针下一个人开始重新从1开始报数,

如此下去直到所有的人全部都出列为止。试设计程序实现,按照出列的顺序打印各人的编号。

@author Administrator

/

public class Question2 {

class person {

int password;

int number;

int state = 1;

public person(int password, int number) {

thispassword = password;

thisnumber = number;

}

public person(int number){

thisnumber = number;

}

}

public int ListLength(List<person> list) {

int count = 0;

if (list != null) {

for (person p : list) {

if (pstate != 0) {

count++;

}

}

}

return count;

}

public void cacle() {

// 初始化数据

List<person> list = new LinkedList<person>();

listadd(new person(3,1));

listadd(new person(1,2));

listadd(new person(7,3));

listadd(new person(2,4));

listadd(new person(4,5));

listadd(new person(8,6));

listadd(new person(4,7));

int position = -1;//初始位置

int m = 20; //第一次报多少的人出来

int count = 0;//已经报了多少人

while (ListLength(list) != 0) {

position = (position + 1) % listsize();// 位置定位

if (((person) listget(position))state != 0) {

count++;

}

if (count == m) {

person p = listget(position);

Systemoutprint(pnumber+" ");

pstate = 0;

m = ppassword;

listset(position, p);

count = 0;

}

}

}

public static void main(String[] args) {

Question2 q= new Question2();

qcacle();

}

}

跟这差不多的。

var

k:longint;

i,j,m,s:longint;

begin

readln(k);

for m:=2 to 9999999 do

begin

i:=2k;

j:=0;

s:=1;

while i>k do

begin

j:=(j+m) mod i;

if j=0 then j:=i;

if j<=k then begin s:=0;break; end;

dec(i);

dec(j);

end;

if s=1 then begin writeln(m);halt; end;

end;

end

约瑟夫问题:

#include

struct

Node

{

int

data;

Node

pNext;

};

void

main()

{

int

n,k,m,i;

Node

p,q,head;

cout<<"输入n的值:";

cin>>n;

cout<<"输入起始报数人号码k的值:";

cin>>k;

cout<<"输入

数到m出列的m的值:";

cin>>m;

head=(Node)new

Node;

//确定头结点

p=head;

for(i=1;i<=n-1;i++)

//赋初值

{

p->data=i;

p->pNext=(Node)new

Node;

//为下一个新建内存

p=p->pNext;

}

p->data=n;

//最后一个单独处理

p->pNext=head;

//指向头,形成循环链表

p=head;

while(p->data!=(p->pNext)->data)

//p->data==(p->pNext)->data表示只剩下一个结点的

{

while(p->data

!=k)

//寻找编号为k的结点

p=p->pNext;

if(m==1)

{

for(i=1;i<=n;i++)

{

cout<

data<<'\t'

;

p=p->pNext

;

}

cout<<'\n';

return;

}

else

for(i=1;i

pNext;

//q为报m的结点

cout<

data<<"\t";

//输出报m的结点的值

k=(q->pNext)->data;

//k为下一个报数的起点

p->pNext=q->pNext;

//删除报m的结点

}

cout<

data<<'\n';

//输出最后一个结点的值

}

约瑟夫环是一个数学的应用问题:已知n个人(以编号1,2,3n分别表示)围坐在一张圆桌周围。从编号为k的人开始报数,数到m的那个人出列;他的下一个人又从1开始报数,数到m的那个人又出列;依此规律重复下去,直到圆桌周围的人全部出列。

链表方法:这个就是约瑟夫环问题的实际场景,有一种是要通过输入n,m,k三个正整数,来求出列的序列。这个问题采用的是典型的循环链表的数据结构,就是将一个链表的尾元素指针指向队首元素。 p->link=head 解决问题的核心步骤:(程序的基本算法) 1建立一个具有n个链结点,无头结点的循环链表; 2确定第1个报数人的位置; 3不断地从链表中删除链结点,直到链表为空。 void JOSEPHUS(int n,int k,int m) //n为总人数,k为第一个开始报数的人,m为出列者喊到的数 { / p为当前结点 r为辅助结点,指向p的前驱结点 list为头节点/ LinkList p,r,list; /建立循环链表/ for(int i=0;i<n;i++) { p=(LinkList)malloc(sizeof(LNode)); p->data=i; if(list==NULL) list=p; else r->link=p; r=p; } p->link=list; /使链表循环起来/ p=list; /使p指向头节点/ /把当前指针移动到第一个报数的人/ for(i=0;i<k;i++) { r=p; p=p->link; } /循环地删除队列结点/ while(p->link!=p) { for(i=0;i<m-1;i++) { r=p; p=p->link; } r->link=p->link; printf("被删除的元素:%4d ",p->data); free(p); p=r->link; } printf("\n最后被删除的元素是:%4d",P->data); }

#include<stdioh>

#include<stdlibh>

struct listNode{

int data;

struct listNode nextPtr;

};

typedef struct listNode LISTNODE;

typedef LISTNODE LISTNODEPTR;/LISTNODEPTR:指向LISTNODE指针/

LISTNODEPTR createList(int n);

void selectKing(LISTNODEPTR headPtr1,int n);

void printList(LISTNODEPTR currentPtr);/打印链表/

void destroyList(LISTNODEPTR headPtr);/释放链表各个结点/

int main()

{

LISTNODEPTR headPtr1=NULL,headPtr2=NULL;

int count,monkeys;

int n;

printf("input the amount of monkeys:");

scanf("%d",&monkeys); /猴子个数/

printf("input the count number:");

scanf("%d",&count); /count=3,表示每次数到3的猴子出局/

headPtr1=createList(monkeys);/创建循环链表/

selectKing(headPtr1,count);/选大王。headPtr1指向循环链表。headPtr2指向由淘汰猴子组成地链表/

system("PAUSE");

return 0;

}

/创建循环链表,容纳n个猴子。返回指向链表头结点的指针/

LISTNODEPTR createList(int n)

{

LISTNODEPTR headPtr=NULL,tailPtr,currentPtr;

int i;

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

currentPtr=(LISTNODEPTR)malloc(sizeof(LISTNODE));

if(currentPtr==NULL)

printf("memory malloc wrong\n");

else{

currentPtr->data=i;

currentPtr->nextPtr=NULL;

if(headPtr==NULL){/若是作为头结点/

headPtr=currentPtr;

tailPtr=currentPtr;

}

else{/将结点追加到链表末尾/

tailPtr->nextPtr=currentPtr;

tailPtr=currentPtr;

}

}

}

tailPtr->nextPtr=headPtr;/形成循环链表/

return headPtr;

}

/从headPtr1指向的循环链表中选大王,数到n的猴子淘汰,将依次淘汰出来的猴子插入到headPtr2指向的链表中/

void selectKing(LISTNODEPTR headPtr1,int n)/n>=2/

{

LISTNODEPTR prePtr1=NULL,currentPtr1,headPtr2=NULL,tailPtr2;

int count;

count=1;

currentPtr1=headPtr1;

while(currentPtr1!=currentPtr1->nextPtr){

/往后数一个猴子/

prePtr1=currentPtr1;

currentPtr1=currentPtr1->nextPtr;

count++;

/若数到n,则淘汰currentPtr指向的猴子/

if(count%n==0){

/从headPtr1指向链表中拆下currentPtr指向的结点/

prePtr1->nextPtr=currentPtr1->nextPtr;

currentPtr1->nextPtr=NULL;

/将currentPtr1指向的结点插入到headPtr2指向链表中/

if(headPtr2==NULL){/若headPtr2指向的为空链表/

headPtr2=currentPtr1;

tailPtr2=currentPtr1;

}

else{ /将拆下来的结点组装到headPtr2指向的链表上/

tailPtr2->nextPtr=currentPtr1;

tailPtr2=tailPtr2->nextPtr;

}

/currentPtr1指向上一个结点,为下一次数数做准备/

currentPtr1=prePtr1;

}

}

printf("大王是:%d\n",currentPtr1->data);

printf("淘汰的猴子是:");

printList(headPtr2);

/释放链表/

destroyList(headPtr2);

free(currentPtr1);

}

/函数功能:遍历链表,打印链表中各结点的值。

参数说明:指向结点的指针,接收链表头接点的值/

void printList(LISTNODEPTR currentPtr)

{

if (currentPtr==NULL)

printf("the list is empty\n");

else{

printf("the list is:\n");

while(currentPtr!=NULL){

printf("%d--->",currentPtr->data);

currentPtr=currentPtr->nextPtr; /currentPtr指向下一个结点/

}

printf("NULL\n\n");

}

}

void destroyList(LISTNODEPTR headPtr)

{

LISTNODEPTR tempPtr;

while (headPtr!=NULL){

tempPtr=headPtr;

headPtr=headPtr->nextPtr;

free(tempPtr);

}

}

以上就是关于C语言编程求解约瑟夫问题全部的内容,包括:C语言编程求解约瑟夫问题、求解约瑟夫环问题(Java)、约瑟夫问题(编程求解)等相关内容解答,如果想了解更多相关内容,可以关注我们,你们的支持是我们更新的动力!

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

原文地址:https://www.54852.com/zz/10108089.html

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

发表评论

登录后才能评论

评论列表(0条)

    保存