list容器 、数组 模拟栈

list容器 、数组 模拟栈

----zoj 4016 Mergeable Stack

题意

模拟题,给出三种操作:

  1. s v 将数字 v 放到 s 栈中
  2. s 输出 s 栈顶元素,并删除
  3. s t 将栈 t 合并到 栈 s 中,顺序不变

这一题数据比较大,所以用stack函数会超时;所以用 list 容器。

关于list

list 就是数据结构中的双向链表,内存空间不连续,不支持快速随机存取。

  • begin() 和 end() 即头指针和尾指针
  • push_back () 和 push_front() 在头部和末端插入元素。
  • empty() 判断是否为空
  • clear() 清空

遍历list

#include<stdio.h>
#include<list>
using namespace std;
int main()
{
    
    
    list<int>l;
    for(int i=0;i<10;i++)
    {
    
    
        l.push_back(i+1);
    }
    list<int>::iterator it;
    for(it=l.begin();it!=l.end();it++)
        printf("%d\n",*it);
    return 0;
}

撸代码:

#include<stdio.h>
#include<algorithm>
#include<list>
using namespace std;
list<long long>s[300010];

/**list stl容器 相当于双向循环链表
*/

int main()
{
    
    
    int t;
    scanf("%d",&t);
    while(t--)
    {
    
    
        int n,q;
        scanf("%d%d",&n,&q);
        for(int i=1;i<=n;i++)
                s[i].clear();
        int op,u,v;
        for(int i=0;i<q;i++)
        {
    
    
            scanf("%d",&op);
            if(op==1)
            {
    
    
                scanf("%d%d",&u,&v);
                s[u].push_back(v);
            }
            else if(op==2)
            {
    
    
                scanf("%d",&u);
                if(!s[u].empty())
                {
    
    
                    /**输出尾部 并且扔掉*/
                    printf("%d\n",s[u].back());
                    s[u].pop_back();
                }
                else
                    printf("EMPTY\n");
            }
            else if(op==3)
            {
    
    
                /**将 v 接到 u 的尾部*/
                scanf("%d%d",&u,&v);
                s[u].splice(s[u].end(),s[v]);
            }
        }
    }
    return 0;
}

数组模拟栈

撸代码:

#include<stdio.h>
#include<list>
#include<string.h>
using namespace std;
const int N = 300010;
int a[N],top[N],bottom[N],nex[N];
/**top记录栈顶和bottom栈底 nex记录栈的元素位置 */
int cnt;
void push(int s,int v)
{
    
    
    a[++cnt]=v;
    if(bottom[s]==0)
    {
    
    
        bottom[s]=cnt;
    }
    /**相当于邻接表 ,看 出栈 就明白了*/
    nex[cnt]=top[s];
    top[s]=cnt;
}
void pop(int s)
{
    
    
    if(top[s]==0)
        printf("EMPTY\n");
    else
    {
    
    
        printf("%d\n",a[top[s]]);
        top[s]=nex[top[s]];
        if(top[s]==0)/**若栈中没有元素,那么buttom标记成0*/
            bottom[s]=0;
    }
}
void mergeStack(int s,int v)
{
    
    
    if(bottom[s]==0)
        bottom[s]=bottom[v];
    nex[bottom[v]]=top[s];///v的栈底 和 s 的栈顶接上
    top[s]=top[v];

    bottom[v]=top[v]=0;
}
int main()
{
    
    
    int t;
    scanf("%d",&t);
    while(t--)
    {
    
    
        memset(bottom,0,sizeof(bottom));
        memset(top,0,sizeof(top));
        memset(nex,0,sizeof(nex));
        cnt=0;
        int n,q;
        scanf("%d%d",&n,&q);
        while(q--)
        {
    
    
            int op,x,y;
            scanf("%d",&op);
            if(op==1)
            {
    
    
                scanf("%d%d",&x,&y);
                push(x,y);
            }
            else if(op==2)
            {
    
    
                scanf("%d",&x);
                pop(x);
            }
            else
            {
    
    
                scanf("%d%d",&x,&y);
                if(bottom[y]==0)
                    continue;/**!!!*/
                mergeStack(x,y);
            }
        }
    }
}

猜你喜欢

转载自blog.csdn.net/DREAM_yao/article/details/106410159