“暴力求解法”的本质是列举法;就理论上而言,它可以解决所有问题,只是时间的长短问题罢了。
但对于“暴力求解法”也是可以进行优化的,我们姑且称优化后的“暴力求解法”为“巧暴”。
具体的操作方法就是充分利用约束条件,以缩小算法计算的范围。
(1)利用题目中的等式条件
(2)利用题目中的不等式条件,进行数学中不等式的缩放
下面就来举两个例子吧!
例1:
输入正整数n,按从小到大的顺序输出所有形如abcde/fghij=n的表达式,
其中a~j恰好为数字0~9的一个排列,2<=n<=79。
样例输入
62
样例输出
79546/01238=62
94736/01528=62
如果我们不采取优化,直接暴力解答,那么需要对10个数字进行全排列,需要计算(10!)次!
优化1: 那我们有没有可能减少需要排列的数字呢?
我们可以发现n的大小是固定的,也就是说,我们可以计算n*【5个数字】的得数,这个得数如果符合我们题目的条件即成立。
这样的话,我们就将需要排列的数字减少到了5个,需要计算(10!/2)次即可!
优化2:但即便是如此,我们仍然需要计算上万次!
那有没有什么办法能够使它减少到百次、千次呢?
答案是肯定的。还记得我们前文中提到的“约束条件”吗?这里就可以派上用场了。
由题,n为正数,因此分子要比分母大;再者,当分子取最大值时,分母才会为最大值。
因此,假设我们的n=62,当我们的分子取98765时,分母有最大值01592。
此时,我们就将分母的取值范围缩小了。
再由于0和1固定不可变,因此计算的次数就成功地变为(1X1X4X7X6)啦!
例2:
输入正整数k,遇到文件末尾结束。找到所有的正整数x和y(x大于等于y),使得1/k=1/x+1/y。输入
一行输入一个正整数k。输出
先在第一行输出解的个数,再每行输出一个表达式。样例输入
2
样例输出
2
1/2 = 1/6 + 1/3
1/2 = 1/4 + 1/4
对于这道题目,咱们就废话不多说,直接进入解题吧!
这道题的约束条件在于不等式“x大于等于y”和等式“1/k=1/x+1/y”。
我们利用数学中的不等式缩放,对x和y的取值进行限制;由此,我们就大大减小了数据量。