励志用更少的代码做更高效的表达
题目描述:
小明的作业本上有道思考题:
看下面的算式:
(□□□□-□□□□)*□□=900
其中的小方块代表0~9
的数字,这10个方块刚好包含了0~9中的所有数字。
注意:0不能作为某个数字的首位。
小明经过几天的努力,终于做出了答案!如下:
(5012-4987)*36=900
用计算机搜索后,发现还有另外一个解,本题的任务就是:请你算出这另外的一个解。
解法一:全排列
这是一道非常经典的全排列类型题!这是一道非常经典的全排列类型题!!这是一道非常经典的全排列类型题!!!
几种分析思路
1 使用多重for循环+判断。 代码量大,且容易出错,10个元素之间互相判定不重复非常非常复杂。 放弃。
2 使用全排列函数。 具体函数的使用方法见博客:传送门
使用全排列函数可以让我们拥有各个位数不相等的十个数字的所有组合! 因此我们只需判断0是否在第一位即可!
代码展示
#include<bits/stdc++.h>
using namespace std;
int main() {
int a[10] = {
0,1,2,3,4,5,6,7,8,9};
int num = 0;
do{
if(a[0]!=0 && a[4]!=0 && a[8]!=0) {
int x1 = a[0]*1000+a[1]*100+a[2]*10+a[3];
int x2 = a[4]*1000+a[5]*100+a[6]*10+a[7];
int x3 = a[8]*10+a[9];
if((x1-x2)*x3==900)
printf("(%d-%d)*%d=900\n", x1, x2, x3);
}
}while(next_permutation(a, a+10));
cout << num;
return 0; }
解法二:DFS
本题也可以使用DFS解题, 但并不是叫我们在考场中使用DFS,而是让初学者利用这道简单的题,加深对DFS使用的熟练程度。 (大佬请自动忽略)
DFS没啥好说的,就是模板 。 直接上代码
#include<bits/stdc++.h>
using namespace std;
int a[10];
int vis[10];
void dfs(int step) {
if(step == 10) {
if(a[0]!=0 && a[4]!=0 && a[8]!=0) {
int x1 = a[0]*1000 + a[1]*100 + a[2]*10 + a[3];
int x2 = a[4]*1000 + a[5]*100 + a[6]*10 + a[7];
int x3 = a[8]*10 +a[9];
if((x1-x2)*x3==900) printf("(%d-%d)*%d=900\n", x1, x2, x3);
}
} else
for(int i = 0; i < 10; i++)
if(!vis[i]) {
vis[i] = 1;
a[step] = i;
dfs(step+1);
vis[i] = 0;
}
}
int main() {
dfs(0);
return 0; }
总结与思考
1 蓝桥杯的绝大多数题素有搜索与暴力杯之称,因此对于本题罗列的两种解法:全排列(暴力法)和dfs(搜索法),一定要牢牢掌握!每年真题都有涉及!
2 最重要的一点,我们的目的是解题, 不是炫技! 实用才是王道!