今天是做比赛总结的第二天,今天总结的是用暴力解法解决题目。这种方法常常用在解决例如凑算式等问题的求解上,思路比较简单,所以考点一般设置在对于细节的处理上面,换句话讲,如果细节处理不当,很容易造成丢分。具体来说,有这么一道题,就是典型的暴力解法(第七届蓝桥杯第三题)的应用:
凑算式
B DEF
A + --- + ------- = 10
C GHI
这个算式中A~I代表1~9的数字,不同的字母代表不同的数字。
比如:
6+8/3+952/714 就是一种解法,
5+3/1+972/486 是另一种解法。
这个算式一共有多少种解法?
乍一看这道题,第一眼的感觉就是使用暴力求解。设置9层循环,暴力枚举,如果最终可以使结果为10,并且没有重复的数字,就将其看作是一种有效的解法,不过也有要特别注意的地方。因为在大多数编程语言里面,存在着类型转换的问题,如果两个int型数据运算,最终的结果也是int型,不会转换成其余的类型,而我们进行的是数学意义上的运算,所以必须要进行类型转换,具体代码如下
package hoLidayPraRewie;
/*
* @author理工吴彦祖
* @Info在校大学生,欢迎交流 妹子优先
*/
public class CountOfEquation {
//总的结果
public static int count=0;
//特别注意这个a1和a2的求法
public static double a1;
public static double a2;
public static void main(String[] args) {
for(int A=1;A<=9;A++){
for(int B=1;B<=9;B++){
for(int C=1;C<=9;C++){
//注意这里的处理非常的细节。第一:在这里设置a1的值,可以节约
//内存空间。第二,B先乘以1.00再除以C,最终得到的是一个浮点数
//而不是一个整型数,提高数据精度,成为数学意义上的乘除
a1=B*1.00/C;
for(int D=1;D<=9;D++){
for(int E=1;E<=9;E++){
for(int F=1;F<=9;F++){
for(int G=1;G<=9;G++){
for(int H=1;H<=9;H++){
for(int I=1;I<=9;I++){
//这里有两个易错点,一个是3位数的表示方法,另一个是
//最终要乘以一个1.00
a2=(D*100+E*10+F)*1.00/(G*100+H*10+I);
//如果可以使结果为10,判断是否是满足条件
//的填写方法
if(A+a1+a2==10){
//这是一个小套路,因为java的
//整型数组初始化时,数组的每个元素
//默认为0。由于A~I的取值范围为
//1~9,所以如果A~I不一样时,最终
//我们的数组a中的所有数都为1,这时
//就是一种符合条件的解法,否则不是
int[] a=new int[10];
a[A]++;a[B]++;a[C]++;a[D]++;
a[E]++;a[F]++;a[G]++;a[H]++;
a[I]++;
for(int i=1;i<=9;i++){
//如果i不等于1,说明A~I中有重复变量
//此时直接退出循环,填入新的数字
if(a[i]!=1)
break;
//能执行到这一步,说明前面的A~都不一样
//,此时就可以使计数器加一了,这是一个易错点
if(i==9)
count++;
}
}
}
}
}
}
}
}
}
}
}
System.out.println(count);
}
}
/* 答案:29
**/
这是暴力求解法的一种典型应用,优点是简单,容易理解,缺点是花费的时间长(敲代码的时间长,机器运行的时间也长),但要特别注意几个易错点,毕竟是比赛题,不会那么简单就得分的。
对于这种题目,如果可以用暴力解法解,一般都可以用回溯法解,真正比赛的时候,最好用回溯法,只有在实在不知道怎么解的情况下,才用暴力解法解。