URAL1915_Titan Ruins: Repeating Success and Failure_复杂度分析、机智

本文针对一种涉及栈操作的问题进行了深入探讨,该问题包含三种基本操作:压栈、弹栈及栈复制。通过分析得知,在特定条件下,栈复制操作并非总是必要,文章给出了具体的优化策略并附带实现代码。

自从知道可以去打上海区域赛了以后就颓得不行再见


题意:

  一个栈,有三种操作,加入一个数,取出一个数,将栈里面的元素复制一遍放到栈顶,给10^6此操作描述,要求对每次取出操作,输出取出的数。


Input

The first line contains the number  n of operations in the experiment (1 ≤ n ≤ 10 6). In each of the following n lines you are given an integer  x (−1 ≤ x ≤ 10 9). If x > 0, then a coin of type x is put on top of the stack. If x = −1, then the top coin is taken from the stack and put into the next hole in the wall. If x = 0, then the stack is copied. It is guaranteed that during the experiment each time a coin was to be removed the stack was not empty.

Output

Output the types of coins removed from the top of the stack in the course of the experiment. The numbers should be given one per line. 


这题简直坑爹,乍一看复制操作肯定要优化的样子,然后基于不用动态空间和空间限制的尿性,仔细一算复制操作最多的操作数,发现才10^7级别,然后就生写,结果不是RE就是MLE,看了别人的代码才发现之前的分析是对的,但是自己忽略了尿性的前提,最多用到10^7的空间,对于栈中已经有大于等于剩余操作数的情况,复制操作没有意义,因为复制以后栈里面前一半的元素已经没用了。复制的时候加一个特判就行了。


代码如下:

#include<iostream>
#include<cstdio>
#include<cstring>
#include<string>
#include<cmath>
using namespace std;
#define mxn 4000010
int num[mxn];
int cur;
int n;
int main(){
	while(scanf("%d",&n)!=EOF){
		cur=0;
		int tem,rec;
		for(int i=0;i<n;++i){
			scanf("%d",&tem);
			if(tem==-1)	printf("%d\n",num[--cur]);
			else if(tem==0){
				if(cur>n-i)	continue;
				rec=cur;
				for(int j=0;j<rec;++j)
					num[cur++]=num[j];
			}
			else	num[cur++]=tem;
		}
	}
	return 0;
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值