刚才的代码中的第一个判断两个数字字符串是否正好数位逆序时,因为根据题意,要判断的两个数字都是4位数,所以判断的逻辑写死在代码里了,这样的缺点是这个函数不够灵活,无法适应题目要求变了或者其他应用场合。干脆把这个函数去掉了,改为更通用的方式,即“strcmp(strrev(x1),x2) = 0”是解的一个必要条件。在judgeCharacters函数主要是判断字符串x1中是否包含x2中的所有字符,为了效率起见,这个函数实际上在逻辑上仅仅检验了两个字符串由同一组字符组成的一个必要条件,即检验的是x2是x1的一个字符子集,例如("4567","7777777777")这样的字符串也是判通过的。即judgeCharacters(x1,x2) && judegeCharacters(x2,x1),才能推断出x1和x2的字符组成相同,但在这里只判断一个必要条件就足够可以把不是解的搜索过滤掉了。实际上完备的写法应该是
int judgeCharacters(char *x1,char *x2)
{
int i,length=strlen(x1);
if(length!=strlen(x2)) return 0;
for(i=0;i<length;i++)
if(strchr(x1,x2[i])==NULL || strchr(x2,x1[i])==NULL ) return 0;
return 1;
}
代码如下:
程序代码:
/* code by : hoodlum1980 */
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
/*判断字符串x1是否包含x2中的所有字符,例如,("abcd","dbca")=true,("abcd","aba")=true,("abcd","af")=false; */
int judgeCharacters(char *x1,char *x2)
{
int i=0;
for(;i<strlen(x2);i++)
if(strchr(x1,x2[i])==NULL) return 0; /*如果在字符串x2中有一个字符不在x1中,返回false*/
return 1;
}
void main()
{
int a,b,c,t1,t2,t3;/*x是第一个乘数,第二个乘数是“cba”的形式组成,中间结果是t1,t2,t3*/
unsigned long x,result;
char str1[6],str2[6],str3[6];
clrscr();
for(x=100;x<1000;x++)
{
for(a=1;a<10;a++) /*根据题意,显然a,b,c都不为0*/
{
for(b=1;b<10;b++)
{
if(b==a) continue;
c=a+b; /*这里的c使得t3=t1+t2!*/
if(c>9) continue;
result=(a + b*10 + c*100)*x; /*计算出相乘的结果!*/
if(result<100000 || result>999999) continue; /*最终结果必须是6位数!*/
t1=a*x; /*三个中间结果*/
if(t1<1000 || t1>9999) continue; /*所有中间结果必须是4位数*/
t2=b*x;
if(t2<1000 || t2>9999) continue;
t3=c*x;
if(t3<1000 || t3>9999) continue;
/*把t2和t3打印成字符串*/
itoa(t2,str2,10);
itoa(t3,str3,10);
/*检验t2和t3是否正好数位顺序相反*/
if(strcmp(strrev(str2),str3)!=0) continue;
/*校验t1的字符是否和t2(t3)的字符一致!*/
itoa(t1,str1,10);
if(!judgeCharacters(str1,str3)) continue;
/*到达这里时已经通过了所有的验证,说明这是一个解,输出它!*/
printf("%ld x %d%d%d = %ld, with %d, %d and %d as partial products, is a solution.\n",x,c,b,a,result,t1,t2,t3);
}
}
}
}
[[it] 本帖最后由 hoodlum1980 于 2008-3-30 13:31 编辑 [/it]]