UVA 11111-Generalized Matrioshkas(栈)

时间:2022-09-14 17:04:42

题意:有很多层盒子,盒子里面再套盒子,一个盒子可能套多个独立的子盒子,但子盒子的总体积必须小于该盒子,否则不合法,输入给一行数,负数代表左边,正数代表右边,大小表示其体积,如-2,-1,1,2则表示体积为2的盒子里套一个体积为1的盒子,再比如-5,-2,2,-1,1,5表示体积为5的盒子套两个盒子分别为2和1,题目要求判断给出的一行数是否合法。一定要保证子盒子的体积小于大盒子。比如-5,-4,4,-2,2,5就不合法。

解析:栈的使用,但同时维护另一个值,该盒子剩余能容纳的体积,比如该盒子的体积为5,已经有一个体积为3的盒子,减掉3后还剩2,如果还有子盒子,则子盒子的体积一定要小于2,否则不合法。

代码如下:

#include<cstdio>
#include<cstring>
#include<string>
#include<algorithm>
#include<set>
#include<map>
#include<queue>
#include<vector>
#include<iterator>
#include<utility>
#include<sstream>
#include<iostream>
#include<cmath>
#include<stack>
using namespace std;
const int INF=1000000007;
const double eps=0.00000001;
int go;
int my_stack[40000],leave[40000],elem[40000]; //栈,leave[]代表该盒子剩余容量
bool solve()
{
int rear=0;
memset(leave,0,sizeof(leave));
leave[0]=INF;
for(int i=0;i<go;i++) //扫一遍
{
if(elem[i]<0) //小于0则添加到栈中
{
rear++;
my_stack[rear]=abs(elem[i]);
leave[rear]=abs(elem[i]); //此时的leave[]就等于他的值
}
else
{
if(rear==0) return false; //还未扫完就栈空
if(elem[i]!=my_stack[rear]) return false; //与栈顶元素不相同
if(elem[i]>=leave[rear-1]) return false; //大于或等于大盒子的leave[]
leave[rear-1]-=elem[i];  //减掉
rear--; //出栈
}
}
return rear==0; //最后还要判断是否栈空
}
int main()
{
string line;
while(getline(cin,line))
{
istringstream output(line); //字符串流输入,这样比较方便
int a;
go=0;
while(output>>a)
{
elem[go++]=a;
}
if(go%2){ printf(":-( Try again.\n"); continue; } //不是偶数肯定不合法
if(solve()) printf(":-) Matrioshka!\n");
else printf(":-( Try again.\n");
}
return 0;
}