约瑟夫问题:编号为1,2,..n的n个人按顺时针方向围坐一圈,每人持有一个密码(正整数)。一开始任选一个正整数作为报数上限值m,从第一个人开始按顺时针方向自1开始顺序报数,报到m时停止报数。报m的人出列,将他的密码作为新的m值,从他在顺时针方向上的下一个人开始重新从1报数,如此下去,直至所有人全部出列为止。试设计一个程序求出出列顺序。
M的初值为20;n=7,7个人的密码依次为:3,1,7,2,4,8,4,首先m值为6(正确的出列顺序应为6,1,4,7,2,3,5)
#include<stdio.h> #include<malloc.h> typedef struct LNode { int num,pwd;//pwd是password密码值 struct LNode *next; }*LinkList; //构造线性表,输入各人信息 LinkList code(int n) //人数 { LinkList head,p1,p2;//生成链表,head,p1,p2是结构体变量的指针 int i=1,j; //第几个人,密码 while(i<=n) { p2=(LNode *)malloc(sizeof(LNode));//为p2创建LNode *类型长度为LNode的动态内存 if(i==1) { p1=head=p2; printf("输入每个人的密码值:\n"); scanf("%d",&j); p1->num=i;//赋人的序号 p1->pwd=j;//赋密码值 i++; } else { p1->next=p2; p1=p2; scanf("%d",&j); p1->num=i;//赋人的序号 p1->pwd=j;//赋密码值 i++; } } p1->next=head;//构成一个循环单链表 return head; } //报到上限值者出列 void delete_code(int m,int n,LinkList head)//密码值,人数,首地址 { int i,j; LinkList p1,p2;//生成链表,p1,p2是结构体变量的指针 p1=head; for(i=0;i<n;i++) { for(j=1;j<m;j++) p1=p1->next; printf("%d ",p1->num);//输出报到密码值的人的序号 m=p1->pwd; //对m赋新值 p2=p1->next;//删p2第一步 p1->num=p2->num;//把下一个人的值赋给p1 p1->pwd=p2->pwd;//把下一个人密码赋给p1 p1->next=p2->next;//删p2第二步 } } int main() { int m,n; //报数值,人数 LinkList head;//生成链表 printf("输入初始密码值m:\n"); scanf("%d",&m); printf("输入人数n:\n"); scanf("%d",&n); if(m<=0||n<=0) printf("错误!\n"); else { head=code(n); printf("出列顺序为:\n"); delete_code(m,n,head); } }
约瑟夫问题
最新推荐文章于 2022-10-09 23:47:10 发布