乘式还原2

来源:互联网 发布:json python 编辑:程序博客网 时间:2024/04/29 01:07
  采用五重循环的方法实现对于5个数字的穷举,前面的许多例题中都已见过。循环实现简单易行,但嵌套的层次太多,需要穷举的变量的数量直接影响到循环嵌套的层数,这种简单的实现方法缺少技巧性。本例的程序中给出了另外一种同样功能的算法,该算法的实现思想请阅读程序。

有乘法算式如下:
○○○
× ○○
------------
○○○○
○○○○
------------
○○○○○
18个○的位置上全部是素数(1、3、5或7),请还原此算式。

*问题分析与算法设计
问题中虽然有18数位,但只要确定乘数和被乘数后经过计算就可确定其它的数位。
乘数和被乘数共有5个数位,要求每个数都是质数。完全可以采用穷举的方法对乘数和被乘数进行穷举,经过判断后找出答案。但是这种方法给人的感觉是“太笨了”,因为组成的数字只是质数(4个),完全没有必要在那么大的范围内进行穷举,只需要试探每一位数字为质数时的情况即可。
采用五重循环的方法实现对于5个数字的穷举,前面的许多例题中都已见过。循环实现简单易行,但嵌套的层次太多,需要穷举的变量的数量直接影响到循环嵌套的层数,这种简单的实现方法缺少技巧性。本例的程序中给出了另外一种同样功能的算法,该算法的实现思想请阅读程序。
程序中并没有直接对质数进行穷举,而是将每个质数与1到4顺序一一对应,在穷举时为处理简单仅对1到4进行穷举处理,待要判断产生的乘积是否满足条件时再利用一个数组完成向对应质数的转换。请体会程序中的处理方法。程序中使用的算法实际上是回朔法。

*程序说明与注释
#include<stdio.h>
#define NUM 5 /*需要穷举的变量数目*/
#define C_NUM 4 /*每个变量的值的变化范围*/
int a[NUM+1]; /*为需要穷举的变量开辟的数组*/
/*a[1]:被乘数的百位,a[2]:十位,aa[3]:个位 a[4]:被乘数的十位 a[5]:个位*/
int b[]={0,2,3,5,7}; /*存放质数数字的数组,不使用第0号元素*/
int f(long sum);

int main()
{
int i,not_finish=1;
i=2; /*i:将要进行处理的元素的指针下标。设置初始值*/
a[1]=1; /*为第1号元素设置初始值*/
while(not_finish) /*not_finish:程序运行没结束标记*/
{
while(not_finish&&i<=NUM)
/*处理包括第i个元素在内的后续元素,找出当前条件下的一种各个变量的一种可能的取值方法*/
if(a[i]>=C_NUM) /*当要处理的元素取超过规定的C_NUM时*/
if(i==1&&a[1]==C_NUM)
not_finish=0; /*若1号元素已经到C_NUM,则处理全部结束*/
else a[i--]=0; /*将要处理的元素置0,下标-1(回退一个元素)*/
else a[i++]++; /*当前元素值加1后下标指针加1*/
if(not_finish)
{
long int sum1,sum2,sum3,sum4; /*定义临时变量*/
sum1=b[a[1>*100+b[a[2>*10+b[a[3>; /*计算被乘数*/
/*利用数组的下标与质数的对应关系完成序号1到4向质数的转换*/
sum2=sum1*b[a[5>; /*计算乘数个位与被乘数的部分积*/
sum3=sum1*b[a[4>; /*计算乘数十位与被乘数的部分积*/
if(sum2>=2222&&sum2<=7777&&f(sum2)&&sum3>=2222&&sum3<=7777&&f(sum3))
/*判断两部分积是否满足题目条件*/
if((sum4=sum2+sum3*10)>=22222&&sum4<=77777&&f(sum4))
/*判断乘式的积是否满足题目条件*/
{
printf(" %d/n",sum1); /*若满足题意,则打印结果*/
printf("* %d%d/n",b[a[4>,b[a[5>);
printf("......................../n");
printf(" %d/n",sum2);
printf(" %d/n",sum3);
printf("......................../n");
printf(" %d/n",sum4);
}
i=NUM; /*为穷举下一个可能取值作准备*/
}
}
}
int f(long sum) /*判断sum的每一位数字是否是质数,若不是返回0,若是返回1*/
{
int i,k,flag; /*flag=1:数字是质数的标记*/
while(sum>0)
{
i=sum%10; /*取个位的数字*/
for(flag=0,k=1;!flag&&k<=C_NUM;k++)
if(b[k]==i)
{
flag=1;break;
}
if(!flag) return 0;
else sum=sum/10;
}
return 1;
}

*运行结果
7 7 5
× 3 3
----------
2 3 2 5
2 3 2 5
-----------
2 5 5 7 5


*思考题
以下乘式中,A、B、C代表一确定的数字,○代表任意数字,请复原。
A B C 2 8 6
× B A C × 8 2 6
------------- 答案: ------------
○○○○ 1 7 1 6
○○A 5 7 2
○○○B 2 2 8 8
------------- ----------------
○○○○○○ 2 3 6 2 3 6

原创粉丝点击