您的位置:首页 > 其它

1403 有趣的堆栈

2016-10-05 10:15 148 查看
1403 有趣的堆栈

基准时间限制:1 秒 空间限制:131072 KB 分值

大家都熟悉堆栈操作。一个堆栈一般有两种操作,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
思路:将序列看成括号匹配;当前最末的肯定是),也就是出栈,那么在这个出栈前有4对括号完整匹配,那么对应这个入栈是在i-2*ans[i]-1,的位置,
那么每次你碰到的未操作的都是),然后每次像上面一样去找入栈点就可以了复杂度O(n);


#include<stdio.h>
#include<algorithm>
#include<iostream>
#include<string.h>
#include<stdlib.h>
#include<queue>
#include<set>
#include<vector>
#include<map>
using namespace std;
typedef long long LL;
int str[1000005];
int str1[2*1000005];
int cnt[1000005];
inline bool scan_d(int &num)
{
char in;bool IsN=false;
in=getchar();
if(in==EOF) return false;
while(in!='-'&&(in<'0'||in>'9')) in=getchar();
if(in=='-')
{
IsN=true;num=0;
}
else num=in-'0';
while(in=getchar(),in>='0'&&in<='9')
{
num*=10,num+=in-'0';
}
if(IsN) num=-num;
return true;
}
int main(void)
{
int n;
while(scanf("%d",&n)!=EOF)
{
int i,j;
memset(str1,-1,sizeof(str1));
for(i = 1; i <= n; i++)
{
scanf("%d",&str[i]);
}
int u = n;
for(i = 2*n; i >= 1; i--)
{
if(str1[i]==-1)
{
str1[i] = 0;
str1[i-2*str[u]-1] = 1;
u--;
}
}int ac = 0;
int k = 1;
for(i = 1;i <= 2*n;i++)
{
if(str1[i]==1)
{
u++;
}
else
{
cnt[k++] = u;
}
}
printf("%d",cnt[1]);
for(i = 2;i <= n;i++)
{
printf(" %d",cnt[i]);
}
printf("\n");
}return 0;
}



                                            
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: