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;
}

 

posted @ 2015-08-01 21:05  Emerald  阅读(201)  评论(0编辑  收藏  举报