C趣味程序百例(21)乘式还原
65.乘法归约(2)
的乘法公式如下:
○○○○○○○○○○○○○○○○○问题分析及算法设计
虽然问题中有18位数,但只要确定了乘数和被乘数,就可以通过计算确定其他位数。
乘数和被乘数一共5位数,每个数都要求是质数。我们可以用穷举法穷尽乘数和被乘数,判断后找出答案。但这种方法给人的感觉是“太笨”,因为数字只是质数(4),所以完全没有必要在这么大的范围内穷尽,只需要测试每个数字都是质数时的情况即可。
采用五循环法来实现五个数的穷举列表,这在之前的很多例子中都有看到。loop的实现简单易行,但是嵌套层数太多,需要穷尽的变量个数直接影响loop嵌套层数。这种简单的实现方法缺乏技巧。在这个例子的程序中给出了具有相同功能的另一个算法。这个算法的实现思路请看程序。
在程序中,没有素数的直接枚举,而是每个素数与1到4的顺序一一对应。在枚举的情况下,为了简单起见只枚举1到4,然后在需要判断乘积是否满足条件时,用一个数组来完成向相应素数的转换。请体验一下节目中的处理方法。程序中使用的算法实际上是回溯法。
*程序和程序注释
# include
# define NUM 5/*要穷举的变量个数*/
#define C_NUM 4 /*每个变量的取值范围*/
int a[NUM+1];/*需要穷举的变量的数组*/
/*a[1]:被乘数的分,a[2]:十位数,aa[3]:一位数avoid main()
{
int i,not _ finish = 1;
I = 2;/*i:要处理的元素的指针下标。设置初始值*/
a[1]= 1;/*为第1个元素设置初始值*/
while(not _ finish)/* not _ finish:程序未完成*/
{
while(not _ finish & & I/*处理包括第I个元素在内的后续元素,找出当前条件下每个变量可能的取值方法*/
if(a[i]>=C_NUM) /*当要处理的元素的值超过指定的C_NUM */
if (I = ./*设置要处理的元素为0,下标-1(后一个元素)*/
else a[i++]++;/*当前元素值加1后,下标指针加1 */
if(not _ finish)
{
long int sum 1,sum2,sum3,sum4/*定义临时变量*/
sum 1 = B[A[1 > * 100+B[A[2 > * 10+B[A[3 >;/*计算被乘数*/
/*利用数组下标与素数的对应关系,完成序号1到4到素数的转换*/
sum 2 = sum 1 * b[a[5 >;/*计算乘数位和被乘数的部分积*/
sum 3 = sum 1 * b[a[4 >;/*计算乘数和被乘数的十位数的部分积*/
If(sum 2 > = 2222 & & sum 2 = 2222 & & sum 3/*判断两部分积是否满足问题条件*/[br/]If((sum 4 = sum 2+sum 3 * 10)> = 2222)/*如果满足问题的含义,打印结果*/
printf ("*% d% d \ n ",b[a[4],b[n
printf("........................\ n ");
printf(" %d\n ",sum 2);
printf(" %d\n ",sum 3);
printf("........................\ n ");
printf(" %d\n ",sum 4);
}
I = NUM;/*为下一个可能的值做准备*/
}
}
}
int f(longsum)/*判断sum的每一位是否为素数,如果不是0,则为1 */
{[/br /*flag=1:一个数是素数的标志*/
while(sum > 0)
{
I = sum;/*取一个数字*/
表示(flag=0,k = 1;!flag & & k if(b[k]= = I)
{
flag = 1;打破;
}
if(!flag)返回0;
else sum = sum/10;
}
return 1;
}:被乘数的十位数a*运行结果
7 7 5
×3 3
-
2 3 2 5
2 3 2 5
-。:一位数*/
int b []。/*存储质数的数组,不使用0号元素*/
int f(长和);
[4]
[5]
*思考问题
下面的乘法公式中,A、B、C代表某个数,○代表任意数。请恢复它。
A B C 286
×B A C×826
-答案:
○○○○○○○○○○○967
0条评论