约瑟夫问题升级问题
编号为1~N的N个人按顺时针方向围坐一圈,每个人持有一个密码(正整数,可以自由输入),开始人选一个正整数作为报数上限值M,从第一个人按顺时针方向自1开始顺序报数,报道M是停止报数。报M的人出列,将他的密码作为新的M值,从他的顺时针方向上的下一个人开始从1报数,如此下去,直至所有人全部出列为止。
目前代码还没有完善,有些错误,先附上代码:
#include<stdio.h> #include<stdlib.h> typedef int status; typedef struct node { status data; status password; struct node *next; }LinkList; LinkList *create(int n) { LinkList *head,*p1,*p2; int i; head=(LinkList *)malloc(sizeof(LinkList)); p1=head; for(i=1;i<=n;i++) { p2=(LinkList *)malloc(sizeof(LinkList)); p2->data=i; p2->password=rand()%10+1; p1->next=p2; p1=p2; } p1->next=head->next; return head; } void Josephus(LinkList *L) { LinkList *p1,*temp; p1=L->next; int i,m; m=p1->password; while(p1!=p1->next) { for(i=1;i<m-1;i++) { p1=p1->next; } printf("%d->",p1->next->data); temp=p1->next; p1->next=temp->next; m=temp->password; free(temp); } printf("%d\n",p1->data); printf("\n"); } int main() { LinkList *head,*p; int n; scanf("%d",&n); head=create(n); Josephus(head); /* p=head->next; for(int i=1;i<=n;i++) { printf("%d ",p->password); p=p->next; } */ return 0; }
这是修改之后的代码:
#include<stdio.h> #include<stdlib.h> #include<time.h> typedef int status; typedef struct node { status data; status password; struct node *next; }LinkList; LinkList *create(int n) { LinkList *head,*p1,*p2; int i; head=(LinkList *)malloc(sizeof(LinkList)); p1=head; srand((unsigned)time(NULL)); for(i=1;i<=n;i++) { p2=(LinkList *)malloc(sizeof(LinkList)); p2->data=i; p2->password=rand()%10+1;//在使用随机函数时最好先用srand()函数设置随机数种子,保证每次程序运行时随机函数产生的数不相同 p1->next=p2; p1=p2; } p1->next=head->next; p1=head->next; free(head); return p2; } void Josephus(LinkList *L) { LinkList *p1,*temp; p1=L; int i,m; m=p1->password; while(p1!=p1->next) { for(i=1;i<m;i++) { p1=p1->next; } printf("%d->",p1->next->data); temp=p1->next; p1->next=temp->next; m=temp->password; free(temp); } printf("%d\n",p1->data); printf("\n"); } int main() { LinkList *head,*p; int n; scanf("%d",&n); head=create(n); p=head->next; for(int i=1;i<=n;i++)//输出password应该放在调用Josephus(head)之前,否则在Josephus()函数中free()时同时将password删除 { printf("%d ",p->password); p=p->next; } printf("\n"); Josephus(head); return 0; }
一开始将srand()放在循环里面,导致每次产生的n个随机数都是一样的。
其实这是因为srand()函数是一个随机数产生函数,其意思就是指C语言里的随机数都是由它来控制产生的!!!如果在应用srand()函数之前就用随机函数rand(),则相当于使用了srand(1);
而将srand((unsigned)time(NULL));这条语句放在了for循环里,即是用了srand((unsigned)time(0));故此句语句不变的话,产生的随机数就不变!!!
后来就把srand()放在for循环之前。