数位小孩
题目描述#
给出一个区间, 求这个区间内有多少个数字满足如下条件:
-
每相邻两个数位和为素数
-
其中至少一个数位为
-
没有前导
数据范围#
思路#
典型的 数位DP
计算方式为
代表 中符合条件的数字,我们通过从高到低枚举 的每一位来进行记忆化搜索即可
不懂 数位DP 的可以去看下这篇blog
CODE
/********************
Author: Nanfeng1997
Contest: NowCoder
URL: https://ac.nowcoder.com/acm/problem/233129
When: 2022-03-15 14:21:34
Memory: 524288MB
Time: 2000ms
********************/
#include <bits/stdc++.h>
using namespace std;
using LL = long long;
LL dp[11][11][2][2][2];
int a[11], cnt;
bool vis[20];
LL dfs(int pos, int last, bool limit, bool lead, bool flag) {
if(pos == cnt) return flag;
LL &ans = dp[pos][last][limit][lead][flag];
if(ans != -1) return ans; ans = 0;
for(int i = 0; i <= (limit ? a[pos] : 9); i ++ ) {
if(lead) {
ans += dfs(pos + 1, i, limit && i == a[pos], lead && !i, flag || i == 1);
} else if(vis[last + i]) {
ans += dfs(pos + 1, i, limit && i == a[pos], lead && !i, flag || i == 1);
}
}
return ans;
}
LL f(LL x) {
if(!x) return x;
cnt = 0;
memset(a, 0, sizeof a);
memset(dp, -1, sizeof dp);
while(x) a[cnt ++ ] = x % 10, x /= 10;
reverse(a, a + cnt);
return dfs(0, 0, true, true, false);
}
void solve() {
vis[2] = 1, vis[3] = 1, vis[5] = 1, vis[7] = 1;
vis[11] = 1, vis[13] = 1, vis[17] = 1;
LL l, r; cin >> l >> r;
cout << f(r) - f(l - 1) << "\n";
}
int main() {
ios::sync_with_stdio(false);
cin.tie(nullptr);
int T = 1; //cin >> T;
while(T --) solve();
return 0;
}
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 分享一个免费、快速、无限量使用的满血 DeepSeek R1 模型,支持深度思考和联网搜索!
· 基于 Docker 搭建 FRP 内网穿透开源项目(很简单哒)
· 25岁的心里话
· ollama系列01:轻松3步本地部署deepseek,普通电脑可用
· 按钮权限的设计及实现