1 条题解
-
0
自动搬运
来自洛谷,原作者为

_rqy
**搬运于
2025-08-24 21:30:42,当前版本为作者最后更新于2017-12-26 13:09:25,作者可能在搬运后再次修改,您可在原文处查看最新版自动搬运只会搬运当前题目点赞数最高的题解,您可前往洛谷题解查看更多
以下是正文
不明白为什么这题会被扔到“分块”里。
说一下我的做法(顺带一提,目前AC代码中除了打表的之外只有两个,另一个既看不明白有编译不过)。
首先写个暴力,可以发现的时候答案也只有三万多。
我们考虑如果有一个图,每个顶点有一个数,然后从到连边,那么显然某个数的魔法指纹是当且仅当从可以到达它。那么我们从开始广搜(图并不用实际建出来)。
广搜每次拓展时我们需要从出发拓展出所有的。考虑枚举的个位,那么因为的十位与个位差的绝对值是的个位,所以的十位至多有两种可能;同理,确定的十位后,其百位数至多有两种可能...如此做下去,最后最多拓展出个数,其中是的位数。但实际上几乎不可能有那么多数,因为许多选择会使某一位上的数不在范围内(实际上,如果的前两位不等,容易证明,于是平均每个数能扩展出个数)。这个过程可以实现。
不过要注意一点:由于求的定义是相邻两项取绝对值再去掉前导零,所以由求的时候可能要把的最高位重复几遍,这样求出的不变(因为只是多了前导零)。
代码:
#include <algorithm> #include <cstdio> typedef long long LL; bool mm[10000050]; int p[10], A, B; int queue[40000], num, head, tail; void dfs(int x, LL y, int p10) { if (y > B) return; if (x == 0) { int last = y / (p10 / 10); if (!last) return; dfs(x, y + (LL)last * p10, p10 * 10); if (y >= A && y <= B) ++num; if (p10 < B) queue[tail++] = y; return; } int last = y / (p10 / 10), nxt = x % 10; x /= 10; if (last - nxt >= 0) dfs(x, y + p10 * (last - nxt), p10 * 10); if (nxt && last + nxt < 10) dfs(x, y + p10 * (last + nxt), p10 * 10); } int main() { scanf("%d%d", &A, &B); head = tail = num = 0; queue[tail++] = 7; if (A <= 7 && B >= 7) ++num; do for (int i = 0; i < 10; ++i) dfs(queue[head], i, 10); while (++head < tail); printf("%d\n", num); return 0; }
- 1
信息
- ID
- 792
- 时间
- 1000ms
- 内存
- 125MiB
- 难度
- 6
- 标签
- 递交数
- 0
- 已通过
- 0
- 上传者