猫吃老鼠 2

问题描述
    现有n个老鼠围成一圆圈,有一只猫从编号为1 的位置开始吃老鼠,每次都隔n-1个老鼠吃一个,请给出最后一个老鼠的编号?题目要求是任给老鼠数i,输出猫最后吃的老鼠的编号。

    (n>2)

    

    看来猫儿学会勤俭持家了。

 

    这次再想几行代码抓到最长寿的老鼠,不好意思,我没想出来。 如果你知道,一定要告诉我。

 

    先看源码。

 

/

typedef struct _MOUSE
 {
  __int64 num;
  __int64 num10;
  struct _MOUSE* pnext;
 }MOUSE;

#define EAT_NUM 11
BOOL b_output_delnum = FALSE;

BOOL b_top = FALSE;

MOUSE* house(int num)
{
 MOUSE* ph = NULL;
 
 ph = (MOUSE*)malloc(sizeof(MOUSE));
 if(ph==NULL)
 {
  return NULL;
 }
 
 ph->num = num;
 ph->num10 = num;
 ph->pnext = NULL;

 return ph;
}

__int64
n_num(__int64 j)
{
 //char out[124] ="";
 __int64 i = 1;
 __int64 num = j;
 __int64 out = 0;
 while(num>0)
 {
  out += (num%EAT_NUM)*i;
  i *= 10;
  num /= EAT_NUM;
 }
 return out;
}

__int64 num_10(__int64 j)
{
 __int64 i = 1;
 __int64 num = j;
 __int64 out = 0;
 while(num>0)
 {
  out += (num%10)*i;
  i *= EAT_NUM;
  num /= 10;
 }
 return out;
}

 

MOUSE*
sort(MOUSE* phead)
{
 MOUSE* pout = NULL;
 MOUSE* pnote = NULL;
 MOUSE* pinsert = NULL;

 while(phead)
 { 
  if(pout==NULL)
  {
   pout = phead;
   phead = phead->pnext;
   pout->pnext = NULL;
  }
  else
  {
   pnote = pout;
   pinsert = pnote;
   while(pnote->num < phead->num)
   {
    pinsert = pnote;
    pnote = pnote->pnext;
    if(pnote==NULL)
     break;
   }
   pinsert->pnext = phead;
   phead = phead->pnext;
   pinsert = pinsert->pnext;
   pinsert->pnext = pnote;
  }
 }

 return pout;
}



//
// num10 == 1, 10, 100
MOUSE*
expend(MOUSE* phead, __int64 num10, __int64 top)

 MOUSE* pnew = NULL;
 MOUSE* pend = NULL;
 MOUSE* pnote = phead;
 __int64 i = 1;
 __int64 new_num = 0;

 if(phead==NULL)
 {
  i = 0;
  while(i<EAT_NUM)
  {
   if(i>= top)
   {
    b_top = TRUE;
    break;
   }
   if(pend == NULL)
   {
    pend = pnew = (MOUSE*)malloc(sizeof(MOUSE));
    if(pend == NULL)
     return NULL;
   }
   else
   {
    pend->pnext = (MOUSE*)malloc(sizeof(MOUSE));
    if(pend->pnext==NULL)
    {
     return NULL;
    }
    pend = pend->pnext;
   }

   pend->num = i;
   pend->num10 = i+1;
   pend->pnext = NULL;
   i++;
  }
  
  return pnew;
 }

 while(pnote)
 {
  while(i<EAT_NUM)
  {
   new_num = pnote->num + i*num10;
   if(new_num>= top)
   {
    b_top = TRUE;
    break;
   }

   if(pend == NULL)
   {
    pend = pnew = (MOUSE*)malloc(sizeof(MOUSE));
    if(pend == NULL)
     return NULL;
   }
   else
   {
    pend->pnext = (MOUSE*)malloc(sizeof(MOUSE));
    if(pend->pnext==NULL)
    {
     return NULL;
    }
    pend = pend->pnext;
   }

   pend->num = new_num;
   pend->num10 = num_10(new_num)+1;
   pend->pnext = NULL;
   i++;
  }
  i=1;
  pnote = pnote->pnext;
 }

 pend = phead;
 while(pend->pnext)
 {
  pend = pend->pnext;
 }

 pend->pnext = pnew;

 return phead;
}

 

//del 0  ---  EAT_NUM-1
//
MOUSE*
eat(MOUSE* phead, int del)
{
 int i=0;
 MOUSE* pnote = phead; 
 MOUSE* pdel = NULL;
 //int del = 0;

 BOOL flag = FALSE;

 if(NULL == phead->pnext)
  return phead;

 if(del==0)
 {
  phead = pnote->pnext;
  if(b_output_delnum)
    {printf(" %d,", pnote->num10);}
  free(pnote);
  pnote = phead;
  i++;
 }

 i++;
 while(pnote->pnext && pnote->pnext!=pnote)
 {
  if(i++==del)
  {
   pdel = pnote->pnext;
   pnote->pnext = pnote->pnext->pnext;
   if(b_output_delnum)
    {printf(" %d,", pdel->num10);}
   free(pdel);
   pdel = NULL;
  }
  else
  {
   pnote = pnote->pnext;
  }

  if(b_top && pnote->pnext==NULL)
    pnote->pnext = phead;

  if(i== EAT_NUM)
  {
   flag = TRUE;
   i=0;
  }
 }
 return b_top ? pnote : phead;
}

int
my_cat2(int num)
{
 int i = num;
 int yu = 0;
 __int64 num10 = 1;
 int del = 0;
 MOUSE* phead= NULL;
 int result = 0;
 BOOL bfirst = TRUE;
 b_top = FALSE;
 
 if(EAT_NUM<2 || EAT_NUM>10)
  return -1;

 do
 {
  phead = expend(phead, num10, n_num(num));
  phead = sort(phead);
  phead = eat(phead, del);

  yu  = (i - del )%EAT_NUM;
  i = del + ((i-del)/EAT_NUM) *(EAT_NUM-1) + (yu?yu-1:0);
  del = (EAT_NUM-yu)%EAT_NUM;
  num10 *= 10;
 }while( EAT_NUM>2 ? (phead->pnext!=phead) && (phead->pnext!=NULL) : i>1);

 result = phead->num10;
 return result;
}

 

///

源码ok,  写的有点随意。

 

主要函数简介

 

    MOUSE* sort(MOUSE* phead){}

        由于本方法要求 老鼠按编号排队,所以写了这个简单实现的排序函数, 没太考虑效率。

 

    MOUSE*  expend(MOUSE* phead, __int64 num10, __int64 top) 

        扩从老鼠队列, num10 依次输入1,10,100,1000,,,  这个不是十进制的,而是n进制的。 top 是 老鼠的总数, 也是n进制的。

        举个例子吧。

        n=3 , top =5 , phead链中有两个节点,节点的值为1,2,  经过本函数后,链中新添加1个节点 值为4(1+3)。 节点5(2+3) 没有加到链中是因为top =5 。 如果 top >5的话,节点5(2+3)也将加入链中。

        再举个,

         n=4, top =7, phead链中有三个节点,节点的值为1,2,3, 经过本函数后, 新添加2个节点 值为5(1+4), 6(2+4)。

        差不多了。。  至于为什么  n=4时,  phead链中有三个节点,嘿嘿,自己看看代码吧。

 

        MOUSE* eat(MOUSE* phead, int del)   

        吃掉某些老鼠, 具体哪些被吃掉,取决于del 。  del 的取值范围 0  到  EAT_NUM-1。

        老鼠链已经排好了,在这个函数中不关心节点的值,自关心节点在链中的位置,第一个节点位置为0,后边依次加1, 在del +EAT_NUM*i 位置上的节点将被吃掉。  对了,EAT_NUM的值是那个n,每n个老鼠吃一个的那个n。

 

        int  my_cat2(int num)

        主要函数登场, num是老鼠总数。 调前面三个函数,并计算 每次调用时的参数。。。

        关键是 eat()的第二个参数del, 过程挺曲折的。。。

        yu  = (i - del )%EAT_NUM;  是计算 eat()后的余数。

        i = del + ((i-del)/EAT_NUM) *(EAT_NUM-1) + (yu?yu-1:0);   是计算eat()后的老鼠个数。

        del = (EAT_NUM-yu)%EAT_NUM;  是 下次eat()时第几个老鼠倒霉。

 

ok.  不知下次猫儿咋个吃法。

 

 

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值