约瑟夫问题升级问题

编号为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;
}
View Code

一开始将srand()放在循环里面,导致每次产生的n个随机数都是一样的。

其实这是因为srand()函数是一个随机数产生函数,其意思就是指C语言里的随机数都是由它来控制产生的!!!如果在应用srand()函数之前就用随机函数rand(),则相当于使用了srand(1);
而将srand((unsigned)time(NULL));这条语句放在了for循环里,即是用了srand((unsigned)time(0));故此句语句不变的话,产生的随机数就不变!!!

后来就把srand()放在for循环之前。

posted on 2015-09-17 20:51  52Cassie  阅读(172)  评论(0编辑  收藏  举报