Uva 725 Division
题意:给出式子abcde / fghij = N, 其中a, b, c, d,e, f, g, h, i, j代表0~9中的任意数字,不能重复,因此构成两个五位数(可以有前导0),要求这两个数整除为N。题目给出N,求所有满足要求的式子,并且要按除数(被除数也是一样)从大到小输出。一个N对应输出一组答案,每组答案间空一行,如果没有则输出“There are no solutions for N.“
思路:基本思路是枚举。但并不需要将10个数字全排列然后再一一验证。得到N后,就可以求出除数的上限和下限,然后在这上限和下限中枚举除数,寻找符合条件的除数。
除数的上限:因为除数*N得出的数,必须是五位数,所以除数必须满足 除数 * N < 100000, 即除数最大为 ceil(100000 / N)-1, 其中ceil()为天花板函数
除数的下限:如果不考虑N,其实也可以得出除数的下限为 01234, 这个数为各位数不重复且各位均在0~9的最大四位数,类似的,因为除数*N得出的数,必须是五位数,所以除数必须满足 除数 * N >= 10000, 基础数最小为 floor(10000/N) 或 01234, 其中floor()为地板函数,这时需要比较得出除数下限的最大值
一点感悟:虽然是简单题,但多思考几步,追求更快的速度对锻炼思维还是有帮助的。
#include <iostream>
#include <cstring>
#include <cstdio>
#include <cmath>
using namespace std;
bool isOkay(int A, int B) {
int vis[10] = {0};
for(int i=0; i<5; i++) {
vis[A%10] ++;
vis[B%10] ++;
A /= 10;
B /= 10;
}
for(int i=0; i<10; i++) {
if( vis[i] != 1 ) {
return false;
}
}
return true;
}
int main() {
int N;
int Case = 0;
while(cin >> N && N) {
if(Case) {
printf("\n");
}
Case ++;
bool flag = false;
for(int i=10000 / N >= 1234 ? 10000 / N : 1234; i < ceil(100000 / N); i++) {
if( isOkay( i*N, i ) ) {
flag = true;
printf("%.5d / %.5d = %d\n", i*N, i, N);
}
}
if( !flag ) {
printf("There are no solutions for %d.\n", N);
}
}
return 0;
}

浙公网安备 33010602011771号