1403 有趣的堆栈
2015-11-24 20:47
281 查看
[b]1403 有趣的堆栈[/b]
大家都熟悉堆栈操作。一个堆栈一般有两种操作,push和pop。假设所有操作都是合法的并且最终堆栈为空。我们可以有很多方法记录堆栈的操作,
(1) 对每个pop操作,我们记录它之前一共有多少个push操作。
(2) 对每个pop操作,我们记录这个被Pop的元素曾经被压上了几个。
例如:操作push, push, pop, push, push, pop, push, pop, pop, pop
用第一种方法 记录为 2, 4, 5, 5, 5
用第二种方法 记录为 0, 0, 0, 2, 4
这两种记录方法可以互相转化,我们的问题是,给定第二种记录方法的序列,请求出第一种记录方法的序列。
Input
Output
Input示例
Output示例
(()(()()))
第一种方法比较简单,就是记录每个右括号之前有少个左括号,如果我们有这个括号序列,直接扫一遍计数就可以了。
现在的问题变为如何从第二种表示方法的序列中还原出这个括号序列?
第二种表示方法实际上是看每个右括号包含了几对完整的括号。
例如输入0,0,0,2,4,我们来还原括号序列。我们用一个字符串来表示,我们用x表示未知的位置。首先我们知道这个字符串的长度是10,因为有5对括号的存在。
初始字符串: xxxxxxxxxx
我们从后往前扫描数列,也从后往前处理字符串。每次注意第一个遇到的未知的位置一定是右括号,我们根据数列信息,可以计算它对应的左括号的位置。
对于样例(注意每次从右往左第一个x就是右括号的位置)
(1) 处理4, 我们知道左括号和右括号间包含4对括号,所以是8个位置,更新字符串为: (xxxxxxxx)
(2) 处理2, 我们知道左括号和右括号间包含2对括号,所以是4个位置,更新字符串为: (xx(xxxx))
(3) 处理0, 我们知道左括号和右括号间包含0对括号,所以是挨着的,更新字符串为:(xx(xx()))
(4) 处理0, 我们知道左括号和右括号间包含0对括号,所以是挨着的,更新字符串为:(xx(()()))
(5) 处理0, 我们知道左括号和右括号间包含0对括号,所以是挨着的,更新字符串为:(()(()()))
至此,我们还原出这个括号字符串。还原这个序列其实就是从右往左扫一次字符串的过程。每次找到第一个没处理的x,更新为右括号,计算左括号的位置并设置左括号。
再从左到右扫一次可以还原出第一种方法的数列。
daima
大家都熟悉堆栈操作。一个堆栈一般有两种操作,push和pop。假设所有操作都是合法的并且最终堆栈为空。我们可以有很多方法记录堆栈的操作,
(1) 对每个pop操作,我们记录它之前一共有多少个push操作。
(2) 对每个pop操作,我们记录这个被Pop的元素曾经被压上了几个。
例如:操作push, push, pop, push, push, pop, push, pop, pop, pop
用第一种方法 记录为 2, 4, 5, 5, 5
用第二种方法 记录为 0, 0, 0, 2, 4
这两种记录方法可以互相转化,我们的问题是,给定第二种记录方法的序列,请求出第一种记录方法的序列。
Input
第一行一个整数n,表示序列的长度(0 < n <=1000000) 第二行n个整数,表示第二种方法的记录。
Output
一行,空格分隔的n个整数,表示第一种表示方法的序列。
Input示例
5 0 0 0 2 4
Output示例
2 4 5 5 5 题解:其实把入栈对应为括号就理解了。示例对应如下括号序列
(()(()()))
第一种方法比较简单,就是记录每个右括号之前有少个左括号,如果我们有这个括号序列,直接扫一遍计数就可以了。
现在的问题变为如何从第二种表示方法的序列中还原出这个括号序列?
第二种表示方法实际上是看每个右括号包含了几对完整的括号。
例如输入0,0,0,2,4,我们来还原括号序列。我们用一个字符串来表示,我们用x表示未知的位置。首先我们知道这个字符串的长度是10,因为有5对括号的存在。
初始字符串: xxxxxxxxxx
我们从后往前扫描数列,也从后往前处理字符串。每次注意第一个遇到的未知的位置一定是右括号,我们根据数列信息,可以计算它对应的左括号的位置。
对于样例(注意每次从右往左第一个x就是右括号的位置)
(1) 处理4, 我们知道左括号和右括号间包含4对括号,所以是8个位置,更新字符串为: (xxxxxxxx)
(2) 处理2, 我们知道左括号和右括号间包含2对括号,所以是4个位置,更新字符串为: (xx(xxxx))
(3) 处理0, 我们知道左括号和右括号间包含0对括号,所以是挨着的,更新字符串为:(xx(xx()))
(4) 处理0, 我们知道左括号和右括号间包含0对括号,所以是挨着的,更新字符串为:(xx(()()))
(5) 处理0, 我们知道左括号和右括号间包含0对括号,所以是挨着的,更新字符串为:(()(()()))
至此,我们还原出这个括号字符串。还原这个序列其实就是从右往左扫一次字符串的过程。每次找到第一个没处理的x,更新为右括号,计算左括号的位置并设置左括号。
再从左到右扫一次可以还原出第一种方法的数列。
///meek #include<stdio.h> int a[1000001],b[1000001]; int main() { int n; while(~scanf("%d",&n)) { for(int i=1; i<=n; i++) { scanf("%d",&a[i]); if(!a[i]) b[i] = 1; else b[i-a[i]]++, b[i] = 0; } int ans=0; for(int i=1; i<n; i++) ans=ans+b[i], printf("%d ",ans); printf("%d\n",ans+b ); } return 0; }
daima
相关文章推荐
- Spring Aop 注解
- 给自己一个黑苹果
- HMC5883L三轴陀螺仪(模拟IIC读取和传感器校准)
- Java集合概述
- java集合类
- 图解TCP/IP读书笔记(二)
- CentOS Linux 上安装svn服务器
- [2561]:第二小整数
- BZOJ 2724: [Violet 6]蒲公英
- CF 431C k-Tree
- NYOJ 1148-图形寻点
- POJ 3067 Japan 【树状数组 向下更新 向上求和】
- 28.UITableView表视图第三章(移动和编辑删除和添加)
- codeforces 492B
- 解决spring使用动态代理类型转换失败的问题--java.lang.ClassCastException: com.sun.proxy.$Proxy$ cannot be cast to ...
- 图遍历算法实现
- mac compile php for pdo_pgsql
- 折线分割平面
- K60 FlexBus总线液晶调试 SSD1289(ID8989)液晶 补充:FlexBus总线驱动成功
- 贪心算法_乘船问题