版权声明:转载时 别忘了注明出处 https://blog.csdn.net/ZCY19990813/article/details/89105880
Sample Input
2
2 15
1 1 10
1 1 11
1 2 12
1 2 13
3 1 2
1 2 14
2 1
2 1
2 1
2 1
2 1
3 2 1
2 2
2 2
2 2
3 7
3 1 2
3 1 3
3 2 1
2 1
2 2
2 3
2 3
Sample Output
13
12
11
10
EMPTY
14
EMPTY
EMPTY
EMPTY
EMPTY
EMPTY
EMPTY
题意:n个栈, q次操作, 操作1,后面两个数a,b, 代表往a栈中放入b, 操作2,后面一个数a,代表在a栈中取走栈顶元素,
操作3,后面两个数a,b,代表把b栈的元素压入b栈中。
注意:1.栈先进后出。 2.数据量3e5,不能开那么多栈(会内存超限),要用链表来模拟栈的过程。
#include <algorithm>
#include <iostream>
#include <cstring>
#include <cstdlib>
#include <sstream>
#include <cstdio>
#include <vector>
#include <string>
#include <cmath>
#include <stack>
#include <queue>
#include <map>
#include <set>
#define MAX 0x3f3f3f3f
//#define fori(a,b) for(LL i=a;i<=b;i++)
//#define forj(a,b) for(LL j=a;j<=b;j++)
#define mem(a,b) memset(a,b,sizeof(a))
using namespace std;
typedef long long ll;
const double PI = acos(-1);
const ll M=3e5+7;
const ll mod=1e9+7;
struct A //单个链表
{
ll num; //结点的值
A *l; //用来指向前一个元素
A *r; //用来指向后一个元素
};
struct B //多个链表
{
A *head; //每一个链表的头指针
A *endd; //每一个链表的尾指针
}b[M];
int main()
{
// freopen("//home//acm//桌面//in","r",stdin);
ll t,n,q,i,j,e,x,y;
scanf("%lld",&t);
while(t--)
{
scanf("%lld",&n);
scanf("%lld",&q);
for(i=1;i<=n;i++) //首先要把每个结点赋值为空
b[i].head=NULL,b[i].endd=NULL;
for(i=0;i<q;i++)
{
scanf("%lld",&e);
if(e==1)
{
scanf("%lld%lld",&x,&y);
A *t=new A; //创建一个A类型的链表
t->num=y;
t->r=NULL;
if(b[x].head==NULL&&b[x].endd==NULL) //如果现在链表里面没有东西
{
t->l=NULL;
b[x].head=t;
b[x].endd=t;
}
else
{
t->l=b[x].endd;
b[x].endd->r=t;
b[x].endd=t;
}
}
else
if(e==2)
{
scanf("%lld",&x);
if(b[x].head==NULL) //如果现在链表里面没有东西
printf("EMPTY\n");
else //如果现在链表里面有东西,因为当时存的时候,是往链表的后面
{ //插入,所以链表尾就相当与栈顶
A *t=b[x].endd;
printf("%lld\n",t->num);
b[x].endd=t->l;
if(t->l==NULL)
b[x].head=NULL;
delete t; //释放删除结点的空间
}
}
else
if(e==3)
{
scanf("%lld%lld",&x,&y);//y里面的放到x里面
if(b[y].head==NULL) //如果y链表为空,不用操作
continue;
if(b[x].head==NULL) //如果x链表为空,记得把y赋值NULL
{
b[x].head=b[y].head;
b[x].endd=b[y].endd;
b[y].head=NULL;
b[y].endd=NULL;
}
else //如果两个链表里面都有东西,直接将y的头连到x的尾部
{ //在相应更改x的尾指针,y的头指针和尾指针
A *t=b[y].head;
t->l=b[x].endd;
b[x].endd->r=b[y].head;
b[x].endd=b[y].endd;
b[y].head=NULL;
b[y].endd=NULL;
}
}
}
其实用链表模拟栈的操作时间复杂度更低了,重点在操作3上面,直接一步操作就行,如果用栈时间复杂度就更高了。
scanf() 比 cin 复杂度会更低。