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 这种关于滚动条的框架,但是就为了一个体验去使用一个框架好像又不值得,今天 ...
随机推荐
- .NET向WebService传值为decimal、double、int、DateTime等非string类型属性时,服务器端接收不到数据的问题
最近在做CRM项目时,使用C#调用SAP PI发布的WebService服务时遇到的问题: 向WebService传值为decimal.double.int.DateTime等非string类型数据时 ...
- python简介,数据类型,input,if语句
1. python的起源 python的创始人为吉多·范罗苏姆(龟叔Guido van Rossum),1989年的圣诞节期间,龟叔为了在阿姆斯特丹打发时间 决心开发一个新的脚本程序解释器,作为A ...
- Oracle常用傻瓜问题1000问
Oracle常用傻瓜问题1000问 大家在应用ORACLE的时候可能会遇到很多看起来不难的问题, 特别对新手来说, 今天我简单把它总结一下, 发布给大家, 希望对大家有帮助! 和大家一起探讨, 共同进 ...
- linux上面安装svn步骤
一.安装 使用yum,非常简单 yum install subversion 二.配置 2.1.创建仓库 我们这里在/home下建立一个名为svn的仓库(repository),以后所有代码都放在这个 ...
- JZOJ 5913. 林下风气
Description 里口福因有林下风气,带领全国各地高校掀起了一股AK风,大家都十分痴迷于AK.里口福为了打击大家的自信心,出了一道自以为十分困难的题目.里口福有一棵树,第i个节点上有点权ai,他 ...
- python爬虫:利用BeautifulSoup爬取链家深圳二手房首页的详细信息
1.问题描述: 爬取链家深圳二手房的详细信息,并将爬取的数据存储到Excel表 2.思路分析: 发送请求--获取数据--解析数据--存储数据 1.目标网址:https://sz.lianjia.com ...
- [CodeForces948B]Primal Sport(数论)
Description 题目链接 Solution 设f(x)为x的最大质因子 那么由题意易得\(X_1\)的范围在\([X_2-f(X_2)+1,X2]\) 同理\(X_0\)的范围在\([X_1- ...
- 27-Middleware管道介绍
1-Middleware管道介绍,. 如果匹配上/task,则界面只会显示i am task. public void Configure(IApplicationBuilder app, IHost ...
- SSM框架的简单搭建
转:https://blog.csdn.net/zhshulin/article/details/37956105 Spring+SpringMVC+MyBatis spring : 4. ...
- RSA 加解密算法详解
RSA 为"非对称加密算法".也就是加密和解密用的密钥不同. (1)乙方生成两把密钥(公钥和私钥).公钥是公开的,任何人都可以获得,私钥则是保密的. (2)甲方获取乙方的公钥,然后 ...