题目:我是超链接
题意:玩玩具啦
如果打开一个大小为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");
}
}