首先因为这个问题的解的范围我们是不清楚的,可以先考虑一下解的范围以便后面的解题。

那么我们可以大胆猜测这个数的位数应该不会很长,否则除非使用一条与 \(D\) 有关的式子外,不论我们用什么方法都计算不出来了。

进一步观察可以发现,这个数的位数不会超过 \(D\) 的位数的两倍,证明如下(利用反证法):

若 \(N\) 加上 \(D\) 之后不会进位到前 \(|\frac{N}{2}|\) 个位置,那么显然此时 \(N\) 会构成回文串,因为 \(D > 1\) 这是不可能的。

否则,\(|\frac{N}{2}| \sim |D| + 1\) 位必然全为 \(9\),则 \(|\frac{N}{2}| + D \sim |\frac{N}{2}| + 1\) 为必然全为 \(0\),此时不会满足互为反串的要求。

那么一个最简单的思路就浮现出来了,可以考虑枚举 \(N\) 的位数然后计算在这个位数下有多少个数可以满足条件。

注意到我们只需确定后 \(|\frac{n}{2}|\) 个位置即可确定 \(N\),于是可以考虑暴力 \(dfs\) 枚举每个位置填什么然后配合一些剪枝就可以通过本题了。

但是否存在复杂度更优秀的做法呢?是存在的。

同样只考虑最后 \(|\frac{n}{2}|\) 位填什么。

可以发现暴力 \(dfs\) 是不需要的,因为之前位置对当前位置的影响仅在于是否会对当前位置产生进位。

可以考虑使用 \(dp\) 解决这个问题,根据上面的理论可以考虑令 \(f_{i, 0 / 1}\) 表示当前填到第 \(i\) 位之前对这一位是否产生进位的方案数。

但是最终我们无法通过这个状态来确定前 \(|\frac{n}{2}|\) 个数是否合法,同时因为 \(dp\) 状态没办法具体描述每个位置填了什么,因此在 \(dp\) 之后判断是否合法是不可行的。

那么就必须保证在 \(dp\) 的过程中保证每一位都必须合法。

可以发现对于第 \(p\) 位假设填为 \(i\),那么 \(n - p + 1\) 位必然填 \(j = i + D_i + lx\) 其中 \(lx\) 表示是否之前存在进位。

这一位合法的条件当且仅当 \((j + D_{n - p + 1} + rx) \% 10 = i\) (其中 \(rx\) 表示之后是否会进位到 \(n - p + 1\)),且满足之前一位是否需要进位的需求。

于是此时判定的方法就呼之欲出了,只需要在 \(dp\) 的时候多记一维令 \(f_{i, 0 / 1, 0 / 1}\) 表示当前考虑到第 \(i\) 位之前是否会对第 \(i\) 位产生进位,第 \(n - i + 1\) 位是否需要之后产生进位。

转移的时候只需要考虑这一位填什么然后把不合法的情况判掉即可,使用记忆化搜索实现。

#include <bits/stdc++.h>
using namespace std;
#define int long long
#define rep(i, l, r) for (int i = l; i <= r; ++i)
const int N = 20 + 5;
int n, d, ans, a[N], dp[N][2][2];
int read() {
char c; int x = 0, f = 1;
c = getchar();
while (c > '9' || c < '0') { if(c == '-') f = -1; c = getchar();}
while (c >= '0' && c <= '9') x = x * 10 + c - '0', c = getchar();
return x * f;
}
int calc(int x) { int ans = 0; for (; x; x /= 10, ++ans) a[ans + 1] = x % 10; return ans;}
int dfs(int p, int lx, int rx, int L) {
if(p > (L + 1) / 2) return !(lx ^ rx);
if(dp[p][lx][rx] != -1) return dp[p][lx][rx];
int ans = 0;
rep(i, 0, 9) {
int j = (i + lx + a[p]) % 10;
if(p == 1 && !j) continue ;
if((L & 1) && (p == (L + 1) / 2)) {
if(i != j) continue;
ans += dfs(p + 1, i + lx + a[p] > 9, rx, L);
}
else {
if(!rx && j + a[L - p + 1] > 9) continue ;
if(rx && j + a[L - p + 1] < 9) continue ;
if(rx && j + a[L - p + 1] == 9 && i) continue ;
if((j + a[L - p + 1]) % 10 != i && (j + a[L - p + 1] + 1) % 10 != i) continue ;
if(!rx && j + a[L - p + 1] + 1 > 9 && (j + a[L - p + 1]) % 10 != i) continue ;
ans += dfs(p + 1, i + lx + a[p] > 9, (j + a[L - p + 1]) % 10 != i, L);
}
}
return dp[p][lx][rx] = ans;
}
signed main() {
d = read(), n = calc(d);
rep(i, n, 2 * n) memset(dp, -1, sizeof(dp)), ans += dfs(1, 0, 0, i);
printf("%lld", ans);
return 0;
}

AT2582 [ARC075D] Mirrored的更多相关文章

  1. AT2582 Mirrored

    传送门 智障爆搜题 可以发现题目给出的式子可以移项 然后就是\(rev(N)-N=D\) 然后假设\(N=a_1*10^{n-1}+a_2*10^{n-2}+...+a_{n}\) 那么\(rev(N ...

  2. 最长回文子串(Mirrored String II)

    Note: this is a harder version of Mirrored string I. The gorillas have recently discovered that the ...

  3. [AtCoderContest075F]Mirrored

    [AtCoderContest075F]Mirrored 试题描述 For a positive integer \(n\), we denote the integer obtained by re ...

  4. Consistent 与 Mirrored 视角

    Consistent 与 Mirrored 视角 在进行分布式训练时,OneFlow 框架提供了两种角度看待数据与模型的关系,被称作 consistent 视角与 mirrored 视角. 本文将介绍 ...

  5. CentOS RabbitMQ 高可用(Mirrored)

    原文:https://www.sunjianhua.cn/archives/centos-rabbitmq.html 一.RabbitMQ 单节点 1.1.Windows 版安装配置 1.1.1 安装 ...

  6. 【arc075F】Mirrored

    Portal --> arc075_f Solution ​  一开始抱着"我有信仰爆搜就可以过"的心态写了一个爆搜.. ​  但是因为..剪枝和枚举方式不够优秀愉快T掉了q ...

  7. 【ARC075F】Mirrored 搜索/数位dp

    Description ​ 给定正整数DD,求有多少个正整数NN,满足rev(N)=N+Drev(N)=N+D,其中rev(N)rev(N)表示将NN的十进制表示翻转来读得到的数 Input ​ 一个 ...

  8. ARC075 F.Mirrored

    题目大意:给定D,询问有多少个数,它的翻转减去它本身等于D 题解做法很无脑,利用的是2^(L/2)的dfs,妥妥超时 于是找到了一种神奇的做法. #include <iostream> u ...

  9. Atcoder F - Mirrored(思维+搜索)

    题目链接:http://arc075.contest.atcoder.jp/tasks/arc075_d 题意:求rev(N)=N+D的个数,rev表示取反.例如rev(123)=321 题解:具体看 ...

随机推荐

  1. matplotlib 高阶之Transformations Tutorial

    目录 Data coordinates Axes coordinates Blended transformations 混合坐标系统 plotting in physical units 使用off ...

  2. Java实习生常规技术面试题每日十题Java基础(七)

    目录 1. Java设计模式有哪些? 2.GC是什么?为什么要有GC? 3. Java中是如何支持正则表达式. 4.比较一下Java和JavaSciprt. 5.Math.round(11.5) 等于 ...

  3. Java,JDK安装及环境配置

    jdk安装及环境配置 一.jdk安装 1.找到jdk安装包 2.安装jdk 3.安装jre 二.环境变量配置          1.JAVA_HOME JAVA_HOME C:\Program Fil ...

  4. VMware客户端vSphereClient新建虚拟机

    1.说明 VMware客户端工具vSphere Client, 用来连接和管理ESX或ESXi主机(下面称为宿主机), 可以方便的创建.管理虚拟机,并分配相应的资源.宿主机就是使用虚拟化软件运行虚拟机 ...

  5. .net core中Grpc使用报错:The remote certificate is invalid according to the validation procedure.

    因为Grpc采用HTTP/2作为通信协议,默认采用LTS/SSL加密方式传输,比如使用.net core启动一个服务端(被调用方)时: public static IHostBuilder Creat ...

  6. HttpRunner_参数化进阶

    一.获取返回包数据   在提取参数时,当 HTTP 的请求响应结果为 JSON 格式,则可以采用.运算符的方式,逐级往下获取到参数值:响应结果的整体内容引用方式为 content 或者 body,如上 ...

  7. SpringBoot学习笔记一之本地环境基础搭建

    原文链接: https://www.toutiao.com/i6802935050196222471/ 工程创建 Maven创建工程 搜索maven找到project的创建 创建simple proj ...

  8. python驱动SAP完成数据导出(一)

    写在前面 我们使用Python驱动SAP时,经常会需要导出一些SAP报表数据至本地Excel文件.这个看似简单的问题背后,其实暗藏玄机,今天小爬就带各位同学好好捋捋. 以事务代码FB03(凭证清单)为 ...

  9. IDEA maven 项目修改代码不生效,mvn clean、install 后才生效

    Maven项目进行修改代码后我们重新运行代码,查看我们target目录下的class文件是否发生了变化.    如何查看class文件,鼠标移到项目,点击右键,然后点击 show in Explore ...

  10. Java中生成一个唯一值的方式

    现总结几种生成一个唯一值的方式 第一种:采用nanoTime() // 理论上存在重复的可能,可以在后面再加上一个随机字符串 Random r = new Random(); for (int i = ...