鬼谷子 猜数问题

来源:互联网 发布:oracle数据库安装视频 编辑:程序博客网 时间:2024/06/11 14:13

这个问题的答案是13和4,原理我这里先不解释,先贴一段解决这个问题的代码 ,如下所示:

void Guess()

{

int Num = 100;
 int y = 0;
 BOOL find = FALSE;
 int *PrimeBuffer = new int[100];
 memset(PrimeBuffer, 0 , sizeof(int) * 100);
 int *PrimeNum = new int[100];
 memset(PrimeNum,0, sizeof(int) * 100);
 int *Sum = new int[200];
 memset(Sum ,  0, sizeof(int) * 200);
 int index = 1;
 PrimeNum[0] = 2;
 PrimeBuffer[2] = 1;
 //TRACE("2/n");
 for(int i = 3 ; i < Num; i++)
 {
  find = FALSE;
  y  = (int)sqrt((double)i);
  for(int j = 2; j <= y; j++)
  {
   if(i % j == 0)
   {
    find = TRUE;
    break;
   }
  }
  if(!find)
  {
   //TRACE("%d/n",i);
   PrimeNum[index++] = i;
   PrimeBuffer[i] = 1;
  }
 }
 //TRACE("%/n/n");
 for(int k = 0; k < index - 1 ; k++)
 {
  for(int m = k + 1 ; m < index ; m++)
  {
   Sum[PrimeNum[k] + PrimeNum[m]] = 1;
  }
 }
 
 
 BOOL bCanKeep = FALSE;
 for(k = 7 ; k < 198; k++)
 {
  if(!Sum[k])
  {
   int step = 0;
   int controller = 0;
   if(k % 2)
   {
    controller = (k - 1) / 2;
    if(k > 99)
    {
     step = (99 - 2) - (controller + 1) + 1;
    }
    else
    {
     step = (k - 2) - (controller + 1) + 1;
    }
    if(step <= 0)
     step = 1;
   }
   else
   {
    controller = (k - 2)  / 2;
    if(k > 99)
    {
     step = (99 - 2) - (controller + 2) + 1;
    }
    else
    {
     step = (k - 2) - (controller + 2) + 1;
    }
    if(step <= 0)
     step = 1;
   }
    
   for(int n = controller; step > 0; n--, step--)
   {
    int remain = k - n;
    if(PrimeBuffer[n] == 1) // at least the first one is prime num
    {
     if(PrimeBuffer[remain] == 1)
     {
      MessageBox("error");
      delete PrimeNum;
      delete PrimeBuffer;
      delete Sum;
      return;
     }
     else//indicate the remain is a compound num,try to split it
     {
      //just here I will company my girl friend  to do some business
      for(int iter = 2; iter < remain / 2 + 1; iter++)
      {
       if(remain % iter == 0)
       {
        if(n * iter < 99)
        {
         bCanKeep = TRUE;
         break;
        }
        else
        {
         bCanKeep = FALSE;
         //Sum[k] = 0;
         break;
        }
       }
      }//end for

     }//end if
    }//end if
    else// the first one is compound num now check the second num
    {
     if(PrimeBuffer[remain] == 1)
     {
      for(int iter = 2; iter < n / 2 + 1; iter++)
      {
       if(n % iter == 0)
       {
        if(remain * iter < 99)
        {
         bCanKeep = TRUE;
         break;
        }
        else
        {
         bCanKeep = FALSE;
         //Sum[k] = 0;
         break;
        }
       }
      }
     }
     else //this condition indicate that the two nums are both compound. a little bit complicated.
     {
      int mul = remain * n;
      for(int mul_iter = 2 ; mul_iter <= 99 ; mul_iter++)
      {
       if(mul % mul_iter == 0)
       {
        int mul_remain = mul / mul_iter;
        if(mul_remain < 99)
        {
         if(mul_remain != remain && mul_remain != n && mul_iter != remain && mul_iter != n)
         {
          bCanKeep = TRUE;
          break;
         }
        }
       }
      }
     }
    }//endif
    if(!bCanKeep)
    {
     Sum[k] = 1;
     bCanKeep = FALSE;
     break;
    }
   }// end for
   
  }//end if
 }
 //print it now
 TRACE("庞涓的可能的答案集合/n");
 for(k = 7; k < 198; k++)
 {
  if(!Sum[k])
  {
   TRACE("%d/n",k);
  }
 }
 TRACE("----------------------------/n");
 //好了,从庞涓的话中我们可以得出上面的存在的和数,下面我们从孙滨的话中来找近一步的答案。
 int FindTime = 0;
 CList<SSTRUCT,SSTRUCT&> S_Answer;
 SSTRUCT s;
 memset((void*)&s,0,sizeof(SSTRUCT));
 int s_iter;
 int *mul_buffer = new int[10000];
 memset(mul_buffer,1,sizeof(int) * 10000);
 mul_buffer[3 * 3 * 3] = 0;
 mul_buffer[5 * 5 * 5] = 0;
 mul_buffer[7 * 7 * 7] = 0;

 for( i  = 0; i < index - 1; i++)
 {
  for(int j = i + 1; j < index ; j++) 
  {
   mul_buffer[PrimeNum[i] * PrimeNum[j]] = 0;
  }
 }

 TRACE("孙滨的可能的答案集合/n");
 BOOL bDel = FALSE;
 BOOL bAdd = FALSE;
 for(s_iter = 12; s_iter <= 9702; s_iter++)
 {
  bDel = FALSE;
  bAdd = FALSE;
  if(mul_buffer[s_iter])//此数还可以分解
  {
   int limit = s_iter / 2 + 1;
   int remain = 0;
   int temp_a1 = 0;
   int temp_a2 = 0;
   for(int div = 2 ; div < limit ; div++)
   {
    if(s_iter % div == 0)
    {
     remain = s_iter / div;
     if(remain <= 99 && div <= 99)
     {
      if(Sum[remain + div] == 0)
      {
       if(temp_a1 == 0 && temp_a2 == 0)
       {
        temp_a1 = remain;
        temp_a2 = div;
        bAdd = TRUE;
       }
       else
       {
        if(remain != temp_a1 && remain != temp_a2 && div != temp_a1 && div != temp_a2)
        {
         bDel = TRUE;
         bAdd = FALSE;
         break;
        }
       }
      }
     }

    }
   }//end for
   if(bDel)
   {
    mul_buffer[s_iter] = 0;
   }
   else
   {
    if(bAdd)
    {    
     
     TRACE("temp_a1 = %d/t temp_a2 = %d/t sum = %d/n",temp_a1,temp_a2,temp_a1 + temp_a2);
     s.a1 = temp_a1;
     s.a2 = temp_a2;
     s.sum = temp_a1 + temp_a2;
     s.mul = 1;
     int ListCount = S_Answer.GetCount();
     BOOL bListFind = FALSE;
     if(ListCount)
     {
      POSITION pos = S_Answer.GetHeadPosition();
      for(int list_iter = 0; list_iter < ListCount ; list_iter++)
      {
       SSTRUCT& S_Temp = S_Answer.GetNext(pos);
       if(s.sum == S_Temp.sum)
       {
        S_Temp.mul++;
        bListFind = TRUE;
        break;
       }
      }
     }
     else
     {
      S_Answer.AddTail(s);
     }
     if(!bListFind && ListCount)
     {
      S_Answer.AddTail(s);
     }
    }

   }
  }//end if
 
 }//好了,现在结束了对孙膑的分析,并且得到了他的答案集合。下面再分析庞涓的第三句话,就可以得到结果了。
 int ListCount = S_Answer.GetCount();
 POSITION pos = S_Answer.GetHeadPosition();
 int a1 = 0,a2 = 0;
 TRACE("这两个数字是:/n");
 for(int list_iter = 0; list_iter < ListCount ; list_iter++)
 {
  SSTRUCT S_Temp = S_Answer.GetNext(pos);
  if(S_Temp.mul ==1)
  {
   TRACE("a1 = %d/t  a2 = %d/n",S_Temp.a1,S_Temp.a2);
   a1 =  S_Temp.a1;
   a2 = S_Temp.a2;
  }
 }
 CString str;
 str.Format("a1 = %d   a2 = %d",a1,a2);
 MessageBox(str);
 
 delete PrimeNum;
 delete PrimeBuffer;
 delete Sum;
 delete mul_buffer;
 //都说孙膑比庞涓聪明,从这道题目来看原来庞涓比孙膑聪明。
 //程序写不是太紧凑,有时间再改改。
 //如果是20以内的话都可以手算了。

}

原创粉丝点击