POJ3717 Decrypt the Dragon Scroll
Description
Those who have see the film of "Kong Fu Panda" must be impressive when Po opens the dragon scroll, because nothing was recorded on it! Po was surprising at the situation; Tai Lung and Master Shifu were also surprising since no body believes that the mystic dragon scroll is just a blank paper. After Tai Lung was defeated, Po found Master Wugui’s Diary and know that the dragon scroll recorded some messages long long years ago, but these messages were blurred due to abrasions. Master Wugui has copied these blurred messages and he wants someone to recover these messages. The messages has a specific length, and each position could be digit, '?' or ','. It is known that each message recorded some strictly increasing positive integers (without leading zeroes) separated by commas and Po is asked to recover these numbers.
Input
There are multiple test cases. Each test case contains string in a line represented. The length of the string will not exceed \(500\). The format is shown in the sample input.
Output
If the message has no appropriate solution, print "impossible", else print the decrypted message. If there exists multiple solutions, output the one whose first number is the smallest; if there is a tie, output the one whose second number is the smallest; and so on.
Sample Input
?,10,?????????????????,16,??
?2?5??7?,??
???????????????????????????????,???
Sample Output
impossible
12,50,70,71
1,2,3,4,5,6,7,8,9,10,11,100,101,102
这个题目dp应该很好想,然后就是难得写。
我们用\(f_i\)表示从\(i\)这个位置开始的合法序列第一个数字最大是多少。然后很容易想到dp来求\(f_i\)。
\]
这个\(maxconvert\)的意思是在\([i,j]\)中填数字,\(j+1\)上填',',构造出比\(f_{j+2}\)小最大的数字是多少。
然后这个\(maxconvert\)写起来有些日狗。
我们将\(S_i \sim S_j\)记作\(S\),将\(f_{j+2}\)记作\(pat\)。
我们抓住这一点——我们肯定是要找到最后大的\(id\),使得\(S_1 \sim S_{id-1} = pat_1 \sim pat_{id-1}\),然后\(S_{id} < pat_{id}\),且\(S_{id}\)要填满足的最大值。\(S_{id+1} \sim\)的'?'全部换成'9'。
之后有了\(f\),我们就可以判断有无解了。
但是还要输方案,我们可以采用贪心的思想,每次都填最小的。假设我们已经填好了\(1 \sim i\),要在\(i+2 \sim j\)中填上数字,我们只要保证填的数字小于\(f_{j+2}\)即可。我们可以构造一个\(minconvert(i,j,j+2)\)函数,表示在\([i,j]\)中填数字,使得填出来的数字比\(S_1 \sim S_j-1\)的数字中的最大值大的最小值是多少。当然要保证此数字小于\(f_{j+2}\)。然后这题就做完了。
#include<iostream>
#include<cstdio>
#include<cstdlib>
#include<cstring>
using namespace std;
const int maxn = 510;
char S[maxn]; int N;
struct Node
{
char s[maxn]; int len;
friend inline bool operator <(const Node &a,const Node &b)
{
if (a.len != b.len) return a.len < b.len;
for (int i = 0;i < a.len;++i) if (a.s[i] != b.s[i]) return a.s[i] < b.s[i];
return 0;
}
inline Node &operator=(const Node &a)
{
if (this == &a) return *this;
len = a.len;
for (int i = 0;i < len;++i) s[i] = a.s[i]; s[len] = 0;
return *this;
}
inline Node():len(0) { s[len] = 0; }
}f[maxn],now;
inline void maxconvert(int x,int y,const Node &z)
{
if (y+2 < N&&y-x+1 > z.len) return;//位数多了,gg
Node tmp;
if (y+2 >= N||y-x+1 < z.len)
{
for (int i = x;i <= y;++i) tmp.s[tmp.len++] = (S[i] == '?'?'9':S[i]);
if (tmp.s[0] != '0') f[x] = tmp;
return;
}//位数少了,补9
int id = -1; //位数一样
for (int i = x;i <= y;++i)
{
if (S[i] == z.s[i-x]) continue;
if (S[i] != '?'&&S[i] > z.s[i-x]) { if (id != -1) break; return; }
if (S[i] == '?'&&z.s[i-x] == '0') continue;
if (S[i] == '?'&&z.s[i-x] == '1'&&i == x) continue;
id = i;
if (S[i] != '?'&&S[i] < z.s[i-x]) break;
}
if (id == -1) return;
for (int i = x;i < id;++i) tmp.s[tmp.len++] = z.s[i-x];
if (S[id] == '?') tmp.s[tmp.len++] = z.s[id-x]-1;
else tmp.s[tmp.len++] = S[id];
for (int i = id+1;i <= y;++i) tmp.s[tmp.len++] = (S[i] == '?'?'9':S[i]);
if (tmp.s[0] != '0') f[x] = tmp;
}
inline bool minconvert(int x,int y,const Node &z)
{
if (y-x+1 < now.len) return false;//位数多了,gg
Node tmp;
if (y-x+1 > now.len)
{
tmp.s[tmp.len++] = (S[x] == '?'?'1':S[x]);
for (int i = x+1;i <= y;++i) tmp.s[tmp.len++] = (S[i] == '?'?'0':S[i]);
if (tmp.s[0] != '0'&&(y+1 >= N||tmp < z))
{
for (int i = x;i <= y;++i) S[i] = tmp.s[i-x];
now = tmp; return true;
}
return false;
}
int id = -1;
for (int i = x;i <= y;++i)
{
if (now.s[i-x] == S[i]) continue;
if (S[i] != '?'&&S[i] < now.s[i-x]) { if (id != -1) break; return false; }
if (S[i] == '?'&&now.s[i-x] == '9') continue;
id = i;
if (S[i] != '?'&&S[i] > now.s[i-x]) break;
}
if (id == -1) return false;
for (int i = x;i < id;++i) tmp.s[tmp.len++] = now.s[i-x];
if (S[id] == '?') tmp.s[tmp.len++] = now.s[id-x]+1;
else tmp.s[tmp.len++] = S[id];
for (int i = id+1;i <= y;++i) tmp.s[tmp.len++] = (S[i] == '?'?'0':S[i]);
if (tmp.s[0] != '0'&&(y+1 >= N||tmp < z))
{
for (int i = x;i <= y;++i) S[i] = tmp.s[i-x];
now = tmp; return true;
}
return false;
}
int main()
{
freopen("3717.in","r",stdin);
freopen("3717.out","w",stdout);
while (scanf("%s",S) != EOF)
{
N = strlen(S);
for (int i = 0;i < N+10;++i) f[i].len = 0;
for (int i = N-1;i >= 0;--i)
{
if (S[i] == ',') continue;
for (int j = i;j < N;++j)
{
if (j+1 >= N||S[j+1] == ','||(S[j+1] == '?'&&j+2 < N&&S[j+2] != ','))
{
maxconvert(i,j,f[j+2]);
if (S[j+1] == ',') break;
}
}
}
now.len = 0; bool fnd = true;
for (int i = 0;i < N;++i)
{
if (S[i] == ',') continue;
bool succ = false;
for (int j = i;j < N;++j)
if (j+1 >= N||S[j+1] == ','||(S[j+1] == '?'&&j+2 < N&&S[j+2] != ','))
{
if (minconvert(i,j,f[j+2]))
{
if (S[j+1] == '?') S[j+1] = ',';
succ = true; i = j; break;
}
if (S[j+1] == ',') break;
}
if (!succ) { fnd = false; break; }
}
if (!fnd) puts("impossible");
else puts(S);
}
fclose(stdin); fclose(stdout);
return 0;
}
POJ3717 Decrypt the Dragon Scroll的更多相关文章
- 【构建Android缓存模块】(一)吐槽与原理分析
http://my.oschina.net/ryanhoo/blog/93285 摘要:在我翻译的Google官方系列教程中,Bitmap系列由浅入深地介绍了如何正确的解码Bitmap,异步线程操作以 ...
- bzoj AC倒序
Search GO 说明:输入题号直接进入相应题目,如需搜索含数字的题目,请在关键词前加单引号 Problem ID Title Source AC Submit Y 1000 A+B Problem ...
- FC红白机游戏列表(维基百科)
1055个fc游戏列表 日文名 中文译名 英文版名 发行日期 发行商 ドンキーコング 大金刚 Donkey Kong 1983年7月15日 任天堂 ドンキーコングJR. 大金刚Jr. Donkey K ...
- [转]Decrypt Any iOS Firmware on Mac, Windows, Linux
source:http://www.ifans.com/forums/threads/decrypt-any-ios-firmware-on-mac-windows-linux.354206/ Dec ...
- how to use fiddler and wireshark to decrypt ssl
原文地址: http://security14.blogspot.jp/2010/07/how-to-use-fiddler-and-wireshark-to.html Requirements2 C ...
- 【前端性能】高性能滚动 scroll 及页面渲染优化
最近在研究页面渲染及web动画的性能问题,以及拜读<CSS SECRET>(CSS揭秘)这本大作. 本文主要想谈谈页面优化之滚动优化. 主要内容包括了为何需要优化滚动事件,滚动与页面渲染的 ...
- MUI开发APP,scroll组件,运用到区域滚动
最近在开发APP的过程中,遇到一个问题,就是内容有一个固定的头部和底部. 头部就是我们常用的header了,底部的话,就放置一个button,用来提交页面数据或者进入下一个页面等,效果 ...
- 翻唱曲练习:龙珠改主题曲 【Dragon Soul】龙之魂
首先这是个人翻唱曲: 这个是原版(燃): 伴奏: 翻唱合成为动漫AMV 出镜翻唱: 全民K歌链接: http://kg.qq.com/node/play?s=aYpbMWb6UwoU&g_f ...
- 完美解决,浏览器下拉显示网址问题 | 完美解决,使用原生 scroll 写下拉刷新
在 web 开发过程中我们经常遇到,不想让用户下拉看到我的地址,也有时候在 div 中没有惯性滚动,就此也出了 iScroll 这种关于滚动条的框架,但是就为了一个体验去使用一个框架好像又不值得,今天 ...
随机推荐
- mysql 数据库设计规范
MySQL数据库设计规范 目录 1. 规范背景与目的 2. 设计规范 2.1 数据库设计 2.1.1 库名 2.1.2 表结构 2.1.3 列数据类型优化 2.1.4 索引设计 2.1.5 分库分表. ...
- dubbo 与Spring Cloud 对比
链接:https://www.zhihu.com/question/45413135/answer/242224410 近期也看到一些分享Spring Cloud的相关实施经验,这对于最近正在整理Sp ...
- 浅谈MySQL字符集
Preface MySQL use character set & collation to organize the different charater.It provid ...
- 平衡二叉查找树 AVL 的实现
不同结构的二叉查找树,查找效率有很大的不同(单支树结构的查找效率退化成了顺序查找).如何解决这个问题呢?关键在于如何最大限度的减小树的深度.正是基于这个想法,平衡二叉树出现了. 平衡二叉树的定义 (A ...
- C语言字符篇(二)字符串处理函数
字符串处理函数 1. 拷贝 strcpy 2. 追加 strcat #include <string.h> char *strcpy(char *dest, const char ...
- C语言基础篇(二)运算符
导航: 2.1 算数运算符 2.2 逻辑运算符 2.3 位运算 2.4 赋值运算 2.5 内存访问符号 ----->x<------------->x<------------ ...
- B1091 N-自守数 (15分)
B1091 N-自守数 (15分) 如果某个数 \(K\)的平方乘以\(N\) 以后,结果的末尾几位数等于 \(K\),那么就称这个数为"\(N\)-自守数".例如 \(3×92 ...
- Color Length UVA - 1625 DP
题目:题目链接 题意:输入两个长度分别为n和m的颜色序列,要求按顺序合并成同一个序列,即每次可以把一个序列开头的颜色放到新序列的尾部.对于每个颜色c来说,其跨度L(c)等于最大位置和最小位置之差,输出 ...
- java练习——多态与异常处理
1. 上面的程序运行结果是什么? 2. 你如何解释会得到这样的输出? parent = chlid; 所以child中的方法被赋予parent,所以用child方法输出了child的成员变量: ...
- ST-LINK JLINK JTAG SWD接线图