这道算法设计与分析上的课后题有些有趣,就拿出来讨论一下。
第一眼可能是快乐暴力。□□ 11~99循环 □□□ 111~999循环 □□□□ < 10000
由于每个数字利用一次的原则,可以缩减范围卡一半为 □□ 12 ~ 50 □□□ 123 ~ 500,直接遍历就好了(看题目的话就可以get到,这遍历的 □□ 与 □□□ 不会超过一半范围的,要不然 □□□□会溢出。)
以下是实现代码。
#include<iostream>
using namespace std;
int G2(int a, int b, int c) {//遍历一遍,记录对应数字出现的次数, 判断是否没有重复数字。
int s[10] = {0}, num = 0;
s[a / 10] ++, s[a % 10] ++;
s[b / 100] ++, s[b % 10] ++, s[b / 10 % 10] ++;
s[c / 1000] ++, s[c % 10] ++, s[c / 10 % 10] ++, s[c / 100 % 10] ++;
if(!s[0]) {
for(int i = 0; i < 10; i ++)
if(s[i] == 1) num ++;
if(num == 9) return 1;
}
return 0;
}
void find_fangkuang() {
for(int a = 12; a < 99; a ++)
for(int b = 123; b < 988; b ++) {
if(a * b > 9999) break;
if(G2(a, b, a * b)) cout << a << " * " << b << " = " << a * b << endl;
}
}
int main()
{
find_fangkuang();
return 0;
}