例题7-1 UVA725 Division(21行AC代码)

紫书刷题进行中,题解系列【GitHub|CSDN

例题7-1 UVA725 Division(21行AC代码)

题目大意

给定整数N,按字典序输出满足等式abcde/fghij=N的值,其中a~j[0,9]的一个排列,0可以在首位

思路分析

若是直接枚举0-9的全排列,枚举量为10!,但仔细分析,假设存在等式P/Q=N,因为N已知,只要求出P,即可计算出Q,因此可将枚举量降至 C 10 5 = 30240 C_{10}^5=30240 ,对于每个P,若能整除N,那么只需判断P和Q是否存在重复数字即可。

再仔细思考一下,发现也没有必要枚举所有的P或Q,假设从1234开始枚举Q,只要发现P或Q任意一个位数大于5,说明之后不会存在解,即可停止,这种方式只需1万多次枚举

对于判重存在多种方法:

  • 用set存储每一位,判断是否有重复
  • 用hash表记录个数
  • 排序后看是否为0-9有序序列

注意点

  • 可用sprintf完成数值到字符串的格式转换,注意string此时不可直接作为接受字符串,需用字符数组

AC代码(C++11,分析优化)

#include<bits/stdc++.h>
using namespace std;
int N, num=0;
int main() {
    while (scanf("%d", &N) == 1 && N != 0) {
        if (num != 0) puts(""); num++; // 连续的测试用例间需有空行
        char buf[100]; string s; int cnt=0;
        for (int fj=1234; ; fj++) { // 枚举1234 - 98765
            sprintf(buf, "%05d%05d", fj*N, fj); // 分子,分母转为字符串
            s = buf;
            if (s.size() > 10) break; // 其中一个超过5位数
            unordered_set<char> _set(s.begin(), s.end()); // 判重
            if (_set.size() == 10) { // 刚好整除且无重复数字
                printf("%s / %s = %d\n", s.substr(0,5).c_str(), s.substr(5).c_str(), N);
                cnt ++;
            }
        }
        if (cnt == 0) printf("There are no solutions for %d.\n", N);
    }
    return 0;
}
发布了128 篇原创文章 · 获赞 87 · 访问量 2万+

猜你喜欢

转载自blog.csdn.net/qq_40738840/article/details/104440707
今日推荐