Gym101889E. Enigma(bfs+数位)
比赛链接:传送门
题目大意:
求一个十进制大数S(有部分数位为"?")能被N整除时的最小值,如果没有办法被N整除,输出"*"。
思路:
一个数位上的数值增加1后,对N取模时的贡献可以预处理出来。设为mod[MAX_N]。
先把整个十进制大数置成最小的合法状态,存在res中。(问号置为0或1)
此时的大数对N取模的值是可以计算的。设为val。
如果val为0,res中已经是最大的答案。
如果val不为0,从最右边的"?"开始往左枚举"?"。
维护一个vis数组,vis[k] = true表示已经访问过的问号当中,至少有一种填法使得整个大数对N取模的余数为k。
如果vis[N-val] = true,说明找到了一种填法。因为是从右往左枚举"?"的,第一次得到vis[N-val] = true时,几乎就是最小的了。考虑到当前数位填的数相同时,可能在当前的"?"右边的"?"填数不同,可能导致最小值不同,所以要额外judge一下。更新vis数组时,记录路径,在vis[N-val] = true时,反演路径,对应修改res中对应数位的数值即可。
代码:
#include <bits/stdc++.h> using namespace std;
const int MAX_N = + ;
const int INF = 0x3f3f3f3f; int N;//取模
int len;//S的长度
char S[MAX_N], res[MAX_N];
int mod[MAX_N];//数位取模的值
int val;//work构造模N为val的值
bool vis[MAX_N], tmpvis[MAX_N];//vis[i]能否构造模N为i的值
int fat[MAX_N], fatnum[MAX_N], fatlog[MAX_N];//记录路径 inline bool judge(int pos, int l, int n, int f)
{
if (l == fatlog[fat[pos]]) {
return n < fatnum[fat[pos]];
}
return l < fatlog[fat[pos]];
} bool work()
{
memset(vis, false, sizeof vis);
vis[] = true;
fat[] = -;
fatnum[] = ;
fatlog[] = ;
if (vis[val])
return true; for (int i = ; i <= len; i++) {
int p = len-i;
if (isdigit(S[p]))
continue;
memcpy(tmpvis, vis, sizeof vis);
for (int j = +(i==len); j <= ; j++) {
for (int k = ; k < N; k++) if(vis[k]) {
int pos = ( k+mod[i]*(j - (i==len)) )%N;
if (!tmpvis[pos] || judge(pos, i, j, k)) {
tmpvis[pos] = true;
//可能同时有很多边找到了?不可能。
fat[pos] = k;
fatnum[pos] = j;
fatlog[pos] = i;
}
}
if (tmpvis[val])
return true;
}
memcpy(vis, tmpvis, sizeof vis);
}
return false;
} int main()
{
// freopen("testdata.txt", "r", stdin);
while (~scanf("%s%d", S, &N)) { len = strlen(S);
mod[] = %N;
for (int i = ; i <= len; i++) {
mod[i] = mod[i-]*%N;
} val = ;
for (int i = ; i <= len; i++) {
int p = len-i;
res[p] = S[p];
if (isdigit(S[p])) {
val += (S[p]-'')*mod[i]%N, val %= N;
}
else if (S[p] == '?') {
if (i == len) {
val += mod[i]%N, val %= N;
res[p] = '';
}
else {
res[p] = '';
}
}
}
val = (N-val)%N;
res[len] = '\0';
// printf("%s\n", res); bool ans = work();
if (!ans) {
puts("*");
continue;
} int tmp = val;
while (fat[tmp] != -) {
int f = fat[tmp];
int l = fatlog[tmp];
int n = fatnum[tmp];
int pos = len-l;
res[pos] = n + '';
tmp = f;
}
// printf("%s\n", S);
printf("%s\n", res);
// puts("");
}
return ;
}
/*
1??????????????????????????????? 2 ???????????????????????????????1 2 ?294?? 17 9999??????? 81
*/
Gym101889E. Enigma(bfs+数位)的更多相关文章
- Gym - 101889E Enigma(数位填数+记忆化)
https://cn.vjudge.net/problem/Gym-101889E 1??????????????????????????????? 2 10000000000000000000000 ...
- 【数位dp】Enigma
http://codeforces.com/gym/101889 E 与一般数位dp不同,保存的是能否满足条件,而非记录方案数 代码: #include <iostream> #inclu ...
- hdu3709 Balanced Number (数位dp+bfs)
Balanced Number Problem Description A balanced number is a non-negative integer that can be balanced ...
- 【每日dp】 Gym - 101889E Enigma 数位dp 记忆化搜索
题意:给你一个长度为1000的串以及一个数n 让你将串中的‘?’填上数字 使得该串是n的倍数而且最小(没有前导零) 题解:dp,令dp[len][mod]为是否出现过 填到第len位,余数为mod 的 ...
- BFS+状态压缩 hdu-1885-Key Task
题目链接: http://acm.hdu.edu.cn/showproblem.php?pid=1885 题目意思: 给一个矩阵,给一个起点多个终点,有些点有墙不能通过,有些点的位置有门,需要拿到相应 ...
- hdu1429之BFS
胜利大逃亡(续) Time Limit: 4000/2000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others) Total S ...
- 搜索入门_简单搜索bfs dfs大杂烩
dfs题大杂烩 棋盘问题 POJ - 1321 和经典的八皇后问题一样. 给你一个棋盘,只有#区域可以放棋子,同时同一行和同一列只能有一个棋子. 问你放k个棋子有多少种方案. 很明显,这是搜索题. ...
- HDU 1226 超级密码(数学 bfs)
传送门: http://acm.hdu.edu.cn/showproblem.php?pid=1226 超级密码 Time Limit: 20000/10000 MS (Java/Others) ...
- HDU 1043 Eight 【经典八数码输出路径/BFS/A*/康托展开】
本题有写法好几个写法,但主要思路是BFS: No.1 采用双向宽搜,分别从起始态和结束态进行宽搜,暴力判重.如果只进行单向会超时. No.2 采用hash进行判重,宽搜采用单向就可以AC. No.3 ...
随机推荐
- opencv学习之路(20)、直方图应用
一.直方图均衡化--equalizeHist() #include "opencv2/opencv.hpp" using namespace cv; void main() { 6 ...
- 【Mac AndroidStudio】download gradle fail问题
第一次运行application时,会发现一直在download gradle,而且进度一直卡着.这时,可以直接拷贝download的链接,粘贴到浏览器下载.下载完了.然后,可以用命令行在用户目录下o ...
- Centos-6.5搭建oracle11g RAC集群
一.基本概念 RAC( Real Application Clusters-----真正的应用集群) RAC数据库是Oracle公司数据库的集群解决方案.高可用性解决方案.两个或多个服务器之间通过一个 ...
- visio连接线设置
以下画图是在新建空白模式的 默认的连线,如下图, 通过设置设计模式,可以把直角线编程直的线段, 设置如下图, 效果,如下图, 如果想在上面的图的线加箭头,可以一条一条加,但是,但是效率太低,我们可以通 ...
- Rancher 容器管理平台-实战训练营-免费视频培训
2018年5月-2019年5月免费培训视频(共21期): http://e.vhall.com/user/home/20160226 培训简介: Rancher2.0版基于开源的Kubernete ...
- 【转】Rancher 2.0 里程碑版本:支持添加自定义节点!
原文链接: http://mp.weixin.qq.com/s?__biz=MzIyMTUwMDMyOQ==&mid=2247487533&idx=1&sn=c70258577 ...
- [Java] int 转换为BigDecimal
new BigDecimal(int i); BigDecimal.parseBigDecimal(String.valueOf(int i));
- JVM垃圾回收(一)- 什么是垃圾回收
什么是垃圾回收? 垃圾回收是追踪所有正在被使用的对象,并标注剩余的为garbage.这里我们先从JVM的GC是如何实现的说起. 手动内存管理 在开始介绍垃圾回收之前,我们先复习一下手动内存管理.它是指 ...
- Linux下执行.sh命令出现-bash: ./bin/start.sh: /bin/bash^M: bad interpreter: No such file or directory
原因是 文件的格式是dos,修改为unix 就OK了 查看文件格式 用vim 打开出错的文件 按 ESC键 再按shift+冒号 输入 set ff 回车 可以看见 该文件 ...
- 『TensorFlow』模型保存和载入方法汇总
『TensorFlow』第七弹_保存&载入会话_霸王回马 一.TensorFlow常规模型加载方法 保存模型 tf.train.Saver()类,.save(sess, ckpt文件目录)方法 ...