这个问题的答案是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以内的话都可以手算了。
}