【POJ3195】Generalized Matrioshkas(栈)

题目我是超链接

题意:玩玩具啦

如果打开一个大小为m的玩具,在里面的玩具大小分别是n1,n2,…,nr,它们必须满足n1 + n2 +…+ nr < m。如果是这样的话,我们说玩具m直接包含玩具n1,n2,…,nr。应该明确的一点是:那些包含在n1,n2,…,nr里的玩具不算是直接包含在m里的。

一个一般的嵌套玩具可以表示成一个非空的非零整数序列的形式: a1 a2 … aN 

玩具k用序列中的两个整数−k(左端)和k(右端)来表示,负数在前,正数在后。 

例如,序列: −9 −7 −2 2 −3 −2 −1 1 2 3 7 9 

代表一个嵌套玩具是由六个玩具,即1,2(两个),3,7和9。注意,玩具7直接包含了玩具2和3。注意,第一个玩具2是单独一个,第二个玩具2中包含了玩具1。如果认为第一个-2是和最后一个2搭配,那就是错误的理解。

下面的序列就不是一个合格的嵌套玩具: 
−9 −7 −2 2 −3 −1 −2 2 1 3 7 9 

因为玩具2比玩具1大,玩具1是不能包含玩具2的。 

−9 −7 −2 2 −3 −2 −1 1 2 3 7 −2 2 9 

因为7和2不能同时放在9中。 

−9 −7 −2 2 −3 −1 −2 3 2 1 7 9 

因为玩具3存在不合法嵌套。

你的任务就是编写一个程序来帮助弗拉基米尔判断设计是否成功。

输入 

输入包含多个测试点,每一个测试点都在单独的一行中,每个测试点是一个非零的整数序列,每一个数保证绝对值小于1e7。

输出 
输入和输出要对应起来,按照输入顺序输出。 每个测试点的答案必须是一下的形式之一: 
如果输入描述了一个合法的嵌套玩具matrioshka,那么输出: :-)Matrioshka ! 
否则,答案应该是: :-( Try again.

题解

设立一个栈,其实很简单嘛,原则如下:

1、遇到负数入栈;遇到正数时,如果上一个元素不是自己的绝对值,GG(腰斩了好疼啊)

2、遇到正数时,一并删除自己A和以下的元素B,然后在再下面一个元素C belong[C]+=A; 如果belong[C]>=C的话,GG(哇这个玩具boom啦)

3、最后栈里还有元素,GG(这半个娃没人要呢....)

4、不是一个套娃(哇你们不团结呢)

然后就是这个belong数组,因为是基于数字来加的,所以要清零啊,但是每次一下memset肯定超时没跑了,那我们就每次把出栈的元素belong清零,(你都熬到这个时候没GG肯定belong不会超啊,清零清零!)

还有那些上一次被腰斩的娃娃呢?你被腰斩了肯定连belong都没记下来啊╮(╯▽╰)╭,一定保持为0咯

说起来复杂其实很简单呐

代码

#include <cstdio>
#include <algorithm>
#include <cstring>
using namespace std;
const int N=1e7+5;
int a[N*2],num,strack[N],belong[N],cnt,lj=0;
bool work()
{
	for (int i=1;i<=cnt;i++)
	  if (a[i]<0) strack[++num]=abs(a[i]);
	  else
	  {
	  	if (strack[num]!=a[i]) return false;
	  	belong[strack[num]]=0; num--; belong[strack[num]]+=a[i];
	  	if (num && strack[num]<=belong[strack[num]]) return false;
	  	if (!num) lj++;
	  }
	if (num || lj>1) return false;
	return true;
}
int main()
{
	char ch;
	while (scanf("%c",&ch)!=EOF)
	{
		cnt=0;num=0;lj=0;
		while (ch!='\n')
		{
			int ans=0,ff=1;
			while (ch<'0' || ch>'9') {if (ch=='-') ff=-1;ch=getchar();}
			while (ch>='0' && ch<='9') ans=ans*10+ch-'0',ch=getchar();
		    a[++cnt]=ans*ff;
		}
		if (work()) printf(":-) Matrioshka!\n");
		else printf(":-( Try again.\n");
	}
}


  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值