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\)。

\[f_i = maxconvert(i,j,j+2)
\]

这个\(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的更多相关文章

  1. 【构建Android缓存模块】(一)吐槽与原理分析

    http://my.oschina.net/ryanhoo/blog/93285 摘要:在我翻译的Google官方系列教程中,Bitmap系列由浅入深地介绍了如何正确的解码Bitmap,异步线程操作以 ...

  2. bzoj AC倒序

    Search GO 说明:输入题号直接进入相应题目,如需搜索含数字的题目,请在关键词前加单引号 Problem ID Title Source AC Submit Y 1000 A+B Problem ...

  3. FC红白机游戏列表(维基百科)

    1055个fc游戏列表 日文名 中文译名 英文版名 发行日期 发行商 ドンキーコング 大金刚 Donkey Kong 1983年7月15日 任天堂 ドンキーコングJR. 大金刚Jr. Donkey K ...

  4. [转]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 ...

  5. 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 ...

  6. 【前端性能】高性能滚动 scroll 及页面渲染优化

    最近在研究页面渲染及web动画的性能问题,以及拜读<CSS SECRET>(CSS揭秘)这本大作. 本文主要想谈谈页面优化之滚动优化. 主要内容包括了为何需要优化滚动事件,滚动与页面渲染的 ...

  7. MUI开发APP,scroll组件,运用到区域滚动

    最近在开发APP的过程中,遇到一个问题,就是内容有一个固定的头部和底部.         头部就是我们常用的header了,底部的话,就放置一个button,用来提交页面数据或者进入下一个页面等,效果 ...

  8. 翻唱曲练习:龙珠改主题曲 【Dragon Soul】龙之魂

    首先这是个人翻唱曲: 这个是原版(燃): 伴奏:  翻唱合成为动漫AMV 出镜翻唱: 全民K歌链接: http://kg.qq.com/node/play?s=aYpbMWb6UwoU&g_f ...

  9. 完美解决,浏览器下拉显示网址问题 | 完美解决,使用原生 scroll 写下拉刷新

    在 web 开发过程中我们经常遇到,不想让用户下拉看到我的地址,也有时候在 div 中没有惯性滚动,就此也出了 iScroll 这种关于滚动条的框架,但是就为了一个体验去使用一个框架好像又不值得,今天 ...

随机推荐

  1. 【MYSQL笔记2】复制表,在已有表的基础上设置主键,insert和replace

    之前我自己建立好了一个数据库xscj:表xs是已经定义好的 具体的定义数据类型如下: 为了复制表xs,我们新建一个表名为xstext,使用下列语句进行复制xs,或者说是备份都可以: create ta ...

  2. python基础数据类型之字符串操作

    1.字符串切片ps:字符串是不可变的对象, 所以任何操作对原字符 是不会有任何影响的 s1 = "python最简洁" print(s1[0]) print(s1[1]) prin ...

  3. 前端之HTML和CSS

    html概述及html文档基本结构 html概述 HTML是 HyperText Mark-up Language 的首字母简写,意思是超文本标记语言,超文本指的是超链接,标记指的是标签,是一种用来制 ...

  4. Spring Boot Shiro权限管理--自定义 FormAuthenticationFilter验证码整合

    思路shiro使用FormAuthenticationFilter进行表单认证,验证校验的功能应该加在FormAuthenticationFilter中,在认证之前进行验证码校验. 需要写FormAu ...

  5. redis 面试题

    https://www.cnblogs.com/ftl1012/p/redisExam.html 1. 使用Redis有哪些好处? (1) 速度快,因为数据存在内存中,类似于HashMap,HashM ...

  6. Guava Cache 工具类 [ GuavaCacheUtil ]

    pom.xml <dependency> <groupId>com.google.guava</groupId> <artifactId>guava&l ...

  7. scrapy--json(喜马拉雅Fm)(二)

    学习了对数据的储存,感觉还不够深入,昨天开始对储存数据进行提取.整合和图像化显示.实例还是喜马拉雅Fm,算是对之前数据爬取之后的补充. 明确需要解决的问题 1,蕊希电台全部作品的进行储存 --scra ...

  8. laravel 安装excel扩展

    1,使用Composer安装依赖 在Laravel项目根目录下使用Composer安装依赖: composer require maatwebsite/excel ~2.1 ps:一定要加上~2.1! ...

  9. 006---Django静态文件配置

    静态文件:Js.Css.Fonts.Image等 这个不难.在setting.py文件加一行 # 别名 用户在url地址栏输入127.0.0.1:8000/static/文件 可以直接访问static ...

  10. saltstack plug in

    目录 可插拔的子系统 灵活性 虚拟模块 salt的核心架构提供了一种高速的交流总线,在核心架构的上层,salt暴露出来的特征是:松散耦合,可插拔的子系统. 可插拔的子系统 salt包含20中插件系统, ...