「题解」带分数
(数学老师:你这是最简分数吗你!)
原题目链接:link
这道是深搜,平均用时 \(3000\mathrm{ms}\);个人做法是暴力枚举,用时 \(139\mathrm{ms}\)。
但是我不知道这个同学 (变态) \(130\mathrm{ms}\) 是怎么做到的……
「我的做题历程」:
step1:观察题面。
「带分数中,数字 \(1\sim 9\) 分别出现且只出现一次(不包含 \(0\)),输出该数字 \(N\) 用数码 \(1\sim 9\) 不重复不遗漏地组成带分数表示的全部种数」,先闪出的是深搜,但由于想不出怎么搜,转战暴力。(题型:DFS or 暴力枚举)
step2:思考解法。
抓住带分数构成特点:整数+假分数,即 \(x = a + {b\over c}\ (a,b, c \ne 0)\)(假分数可化简为整数,即分子可以整除分母 \((b = kc,\ c\mid b)\) )。
于是想到先枚举前面的整数 \(a\),然后得到后面的假分数化简的结果 \(k\),通过枚举 \(c\) 来得到 \(b\)。再判断 \(a,b,c\) 是否满足题意即可。
总不能无限枚举吧,来估范围。分子最小为 \(1\),则整数部分最小为 \(2\),分母最大可取 \(9876543\),还能得到当数 \(N\) 大于 \(9876545\) 时无解(然而 \(N \le 10^6\) ,这个 \(N\) 的范围毫无用处)。
step3:完成代码。
代码(抵制学术不端行为,拒绝 Ctrl + C):
#include <bits/stdc++.h>
using namespace std;
const int N = 1e6 + 5;
int n, sum;
bool vis[11]; // 用于判断数码是否重复、遗漏
inline bool nosame(int x) { // 判断一个数的数码是否重复
memset(vis, 0, sizeof vis);
while (x != 0) {
if (vis[x % 10] || x % 10 == 0) {
return false;
}
vis[x % 10] = true;
x /= 10;
}
return true;
}
inline int len(int x) { // 获取该数位数(长度)
int l = 0;
while (x != 0) {
l++;
x /= 10;
}
return l;
}
inline bool nopublic(int a, int b, int c) { // 判断带分数中有无重复的数码
memset(vis, 0, sizeof vis);
while (a != 0) {
vis[a % 10] = true;
if (a % 10 == 0) {
return false;
}
a /= 10;
}
while (b != 0) {
if (vis[b % 10] || b % 10 == 0) {
return false;
}
vis[b % 10] = true;
b /= 10;
}
while (c != 0) {
if (vis[c % 10] || c % 10 == 0) {
return false;
}
vis[c % 10] = true;
c /= 10;
}
return true;
}
inline void get(int x) {
int l = len(n - x);
// 枚举倍数
for (int i = 1; i <= 9876543; i++) { // 分子至少为一,整数部分就只能为二,分母最大可取 9876543
if (nosame(x * i) && nosame(i) && nopublic(x * i, i, n - x) && len(x * i) + len(i) + l == 9) {
printf("%d=%d+%d/%d\n", n, n - x, x * i, i);
sum++;
}
if (len(x * i) + len(i) + l > 9) { // 如果数码大于 9 位就不用再算了
break;
}
}
return;
}
int main() {
freopen("fraction.in", "r", stdin);
freopen("fraction.out", "w", stdout);
while (~scanf("%d", &n)) {
sum = 0;
for (int i = 1; i < n; i++) {
if (nosame(i)) {
get(n - i);
}
}
printf("%d\n", sum);
}
return 0;
}
数据 Hack 了呢~你的 Accepted 被 Hack 掉了吗~( ̄y▽, ̄)╭
让我们来解决 『带分数』 叭~
Bye bye!!1 👋👋