励志用尽量少的代码做高效的表达
题目(提交)链接→UVa-725
题目大意:
0-9不重复的组成两个5位数,如果数A/数B=n,则为可行解。
思路分析:
本题实质是通过巧妙分析的暴力求解法。
下等解法:直接枚举0-9的全排列,枚举量为10!,效率极低。
中等解法:在下等解法的基础上思考,如果我们只遍历一个数的5位,判断该数*
n是否小于10W且两个数中各位是否重复,则最大只需遍历10^5次。
上等解法:在中等解法的基础上思考,被除数最大不会超过100000/n,除数最小为1234,则遍历范围就缩减为 1234 <= i <= 100000/n。
注意:
1、最后可采用域宽填充0的方法输出前导0。
2、使用红黑二叉树set的去重原理巧妙判断数字是否重复出现。
代码:
#include<bits/stdc++.h>
using namespace std;
int main() {
int n, num = 0; //num判断最后一个输出结果后有无空格
while((scanf("%d", &n) == 1) && n) {
if(num != 0) printf("\n"); num++; //连续的测试用例间需有空行
bool flag1 = false;
for(int i = 1234; i < (100000/n+1); i++) //缩小范围
if((i * n) < 100000) {
int i1 = i, i2 = i * n; //分别为除数、被除数
set<int>s;
for(int k = 0; k < 5; k++ ) {
s.insert(i1%10); i1 /= 10; s.insert(i2%10); i2 /= 10;
}
if(s.size() == 10) {
printf("%05d / %05d = %d\n", i*n, i, n); flag1 = true;
}
}
if(!flag1) printf("There are no solutions for %d.\n", n);
}
return 0;
}