题一:18443 除法等式
Description
输入正整数n,按从小到大的顺序输出所有形如abcde/fghij=n的表达式,其中a~j各代表0~9中的一个数字 除了0可以重复外,其它数字不能重复,2<=n<=90000。
输入格式
多case,每行一个数字,最后一个数字是0
输出格式
除了最后一行0不用处理, 其它每个case,按被除数由小到大输出所有满足等式的情况 注:如果没有满足条件的等式,该case结束后,也需要输出一个空行 两个case之间用一个空行分隔
输入样例
44 666 6666 20000 0
输出样例
00176/00004=44 00308/00007=44 00352/00008=44 00572/00013=44 00704/00016=44 00792/00018=44 00836/00019=44 01056/00024=44 01408/00032=44 01584/00036=44 01628/00037=44 01672/00038=44 01760/00040=44 01892/00043=44 01980/00045=44 02068/00047=44 02156/00049=44 02376/00054=44 02948/00067=44 03080/00070=44 03168/00072=44 03256/00074=44 03520/00080=44 03564/00081=44 03740/00085=44 04180/00095=44 04268/00097=44 04312/00098=44 04620/00105=44 04752/00108=44 05720/00130=44 05896/00134=44 05984/00136=44 06028/00137=44 06072/00138=44 06380/00145=44 06908/00157=44 07040/00160=44 07392/00168=44 07920/00180=44 08360/00190=44 08536/00194=44 08976/00204=44 09108/00207=44 09460/00215=44 09504/00216=44 09548/00217=44 10560/00240=44 10780/00245=44 13068/00297=44 14080/00320=44 15268/00347=44 15840/00360=44 16280/00370=44 16720/00380=44 16940/00385=44 17600/00400=44 17820/00405=44 17952/00408=44 18700/00425=44 18920/00430=44 19008/00432=44 19800/00450=44 20108/00457=44 20680/00470=44 20900/00475=44 21560/00490=44 21780/00495=44 23760/00540=44 26004/00591=44 27940/00635=44 29480/00670=44 30140/00685=44 30712/00698=44 30800/00700=44 31020/00705=44 31680/00720=44 31856/00724=44 31900/00725=44 32560/00740=44 35024/00796=44 35200/00800=44 35640/00810=44 35904/00816=44 37400/00850=44 40260/00915=44 40700/00925=44 41008/00932=44 41800/00950=44 42108/00957=44 42680/00970=44 43120/00980=44 45628/01037=44 45672/01038=44 46200/01050=44 47520/01080=44 47652/01083=44 57200/01300=44 58476/01329=44 58960/01340=44 59268/01347=44 59840/01360=44 60280/01370=44 60720/01380=44 60940/01385=44 63800/01450=44 65032/01478=44 67408/01532=44 67892/01543=44 69080/01570=44 69432/01578=44 70048/01592=44 70400/01600=44 72380/01645=44 73920/01680=44 74052/01683=44 79200/01800=44 79420/01805=44 83600/01900=44 84700/01925=44 85360/01940=44 89760/02040=44 90068/02047=44 90376/02054=44 91080/02070=44 91300/02075=44 91740/02085=44 94600/02150=44 95040/02160=44 95348/02167=44 95480/02170=44 27306/00041=666 41958/00063=666 43290/00065=666 52614/00079=666 53946/00081=666 63270/00095=666 20000/00001=20000 40000/00002=20000 60000/00003=20000 80000/00004=20000
提示
提示:6666没有找到满足条件的等式
思路:
显然这是一个暴力枚举的问题,对于枚举而言,私以为大原则有一,关键有三。
大原则,简化问题,简化时间复杂度。
关键一:确定枚举对象
关键二:确定枚举范围
关键三:确定枚举条件,限制条件
最后再处理枚举过程中的细节问题,比如,乘法溢出问题,除法中的数据丢失问题,等等。
对于本题而言,abcde/fghij=n,显然将式子变换abcde=n*fghij,以fghij为枚举对象会更加的方便。
其次就是确定枚举范围,首先,答案为五位数且数字不重复,则易知,abcde<=98765,再根据,n>=2且abcde/n=fghij
则易得,fghij<=49383,那么,枚举范围为[1,49383].
最后,就是枚举条件的判断,一般都是Yes\No的判断。其一,题目给出,不重复数字组成,我们可以对于枚举每个abcde,fghij,用标记数组判断是否重复。
其二,abcde为五位数,我们可以对于枚举的每个abcde判断是否小于等于五位数。其三,逻辑推导出来的限制条件,abcde <=98765。
综上,我们可以比较轻松的写出以下代码:
#include<iostream>
#include<map>
#include<cstdio>
using namespace std;
bool check(int a,int b) {
int vis[10] = {0};
int i = 0;
while(a&&i<5){//判断被除数是否符合
int t = a % 10; ++i;
if (t&&vis[t]) { return false; }
else { vis[t] = 1; }
a /= 10;
}
if (a) { return false;}
while(b){//再结合以上判断结果,判断除数是否符合
int t = b % 10;
if (t && vis[t]) { return false; }
else { vis[t] = 1; }
b /= 10;
}
return true;
}
int main(){
int n;
cin >> n;
while (n) {
for (int a =1; a <= 49383;a++) {
int b = a * n;
if (b > 98765) { break; }
if (check(b,a)) {
printf("%05d/%05d=%d\n",b,a,n);
}
}
cout << endl;
cin >> n;
}
}