dusx1981 发表于 2007-8-24 11:21:58

轮回报数

我写的小程序,题目是:不定数目的人围成一圈,随机找一个从1开始数数,报到3者退出圈子,剩下不到三人停止报数,找出退出圈子的成员.顺序,以及最后留在圈子里的人的最初的报号:
//counts.h
#include <stdio.h>
#include <string.h>
#include <conio.h>
#include <stdlib.h>
typedef struct team
{
int count;
    team * next;
} TEAM;
TEAM * Create_list(int count,TEAM ** globalTail)
{
TEAM * head,*tail,*p;
   
head = tail = NULL;
for(int i = 1; i <= count;i++)
{
p = (TEAM *)malloc(sizeof(TEAM));
p->count = i;
p->next = head;
if(head == NULL)
   head = tail = p;
else
{
   tail->next = p;
      tail = p;
}
}
*globalTail = tail;
return head;
}
TEAM * delete_list(TEAM * head,TEAM * tail,int num )
{
TEAM * p = head;
TEAM * q;
while(p->count != num)
{
      q = p;
p = p->next;
}
if(p->count == num)
{
if(p == head)
{
   head = p->next;
      tail = head;
}

   else
   q->next = p->next;
free(p);
}
return head;
}
TEAM * note_list(TEAM * head,TEAM * tail,int count)
{
TEAM * p = head,*q = NULL;
int note = 1;
int num = 0;
int rest = 0;
while(count >= 3)
{
if((note)%3 != 0)
            p = p->next;
      else
{
   q = p->next;
   num = p->count;
   printf("\nThe out num is %d",num);
            delete_list(head,tail,num);
   p = q;
   --count;
}
++note;
}
   
for(int i = 1;i <=count;i++)
{
printf("\nThe left is %d",p->count);
p = p->next;
}
return head;
}

#include "Counts.h"

void main()
{
        TEAM *tail;
        int n;
        printf("Please input the Number:\n");
        scanf("%5d",&n);
        TEAM * head = Create_list(n,&tail);
        note_list(head,tail,n);
}

有的值能成功运行,有的却不行,请高手指点,谢谢

[ 本帖最后由 dusx1981 于 2007-8-24 14:09 编辑 ]

hobby! 发表于 2007-11-29 16:53:35

用两个数组,一个数组放原数值(人),另一个数组放退出圈的值(人),
第一个数组被出圈的值(人)值归0,第二个数组在0位设一个记数器记录现在到第几位.
第一个数组里用if将0的不计进,(第一个数组也要一个记数器,记录,游戏的数数规则的现在数到几)
第一个数组都是从到头到尾进很处理.头..尾...头..尾...头..尾........完

这样思路就很清楚,也不会出错!

[ 本帖最后由 hobby! 于 2007-11-29 16:58 编辑 ]

hobby! 发表于 2007-11-29 17:01:47

对简单的问题,要用白Z的方法,正如你用户复杂的方法,对系统来讲不是件好事,而且如果问题更复杂,也要只是用户多个简单方法分工分时地处理(外面看上是复杂的).关键是你的逻辑构想!

hobby! 发表于 2007-11-29 17:02:47

看上去简结,才是高招

heyibo213 发表于 2008-1-10 08:55:05

呵呵,这是经典的猴子选大王的题目。
下面是我的代码,已经通过,可以参考一下。:)
/*
*题目:猴子选大王
*方法:建立循环链表
*/

#include <stdio.h>
#include <stdlib.h>

#define NUM 10            /*猴子的个数*/
#define M   3               /*报数到M的猴子退出*/

typedef struct monkey
{
        int ID;
        struct monkey *link;
}MONKEY;

/*
*建立循环链表
*猴子的总个数为n个
*/
MONKEY *createList(int n)
{
        MONKEY *head, *p, *last;
        int i;
        head = NULL;
        for (i=1; i<=n; i++)
        {
                p = (MONKEY *)malloc(sizeof(MONKEY));
                p->ID = i;

                if (head == NULL)   /*建立头节点*/
                        head = p;
                else                    /*建立后面的节点*/
                        last->link = p;
               
                last = p;
                last->link = head;/*让尾指向头*/
        }

        return head;
}

/*
*从循环链表中得到猴子大王
*报数到n的猴子退出竞选
*/
int getMonkeyKing(MONKEY *head, int n)
{
        MONKEY *p, *q;
        int i;
       
        p=head;
        while(p != p->link)
        {
          for(i=1; i<n; i++)         /*寻找报数到n的猴子*/
          {
                  q = p;
                  p = p->link;                  
          }
          q->link = p->link;         /*出列*/
          p = p->link;
        }

        return p->ID;
}

/*主函数*/
int main()
{
        MONKEY *head;
        int i;
       
        head = createList(NUM);
        i = getMonkeyKing(head,M);

        printf("%d\n",i);
        return 0;
}

dusx1981 发表于 2008-2-2 22:55:08

谢谢各位
页: [1]
查看完整版本: 轮回报数