STL栈与队列的操作

栈定义:栈是限定只能在表的一端进行插入和删除的线性表。在表中允许插入和删除的一端叫做栈顶(top);表的另一端则叫做栈底(bottom)。栈又称后进先出(Last In First Out,简写为LIFO)表。

•栈满:栈内元素个数为MaxSize时。top=MaxSize-1

•栈空:栈内无元素。top=-1

•上溢:当栈满时,还要进栈。

•下溢:当栈空时,还要出栈。

 

队列定义:队列是一种特殊的线性表。在队列中,仅允许一端进行插入,在另一端进行删除。允许插入的一端叫做队尾(rear);允许删除的另一端叫做队头(front)。队列又称先进先出(First in First Out,简写为FIFO)表。

 

栈(statck)这种数据结构在计算机中是相当出名的。栈中的数据是先进后出的。栈只有一个出口,允许新增元素(只能在栈顶上增加)、移出元素(只能移出栈顶元素)、取得栈顶元素等操作。在STL中,栈是以别的容器作为底部结构,再将接口改变,使之符合栈的特性就可以了。

使用标准库的栈和队列时,先包含相关的头文件

#include<stack>
#include<queue>


定义栈如下:

stack<int>stk;

定义队列如下:

queue<int>q;

栈提供了如下的操作

s.empty()       如果栈为空返回true,否则返回false
s.size()        返回栈中元素的个数
s.pop()        删除栈顶元素但不返回其值
s.top()        返回栈顶的元素,但不删除该元素
s.push()        在栈顶压入新元素

队列提供了下面的操作

q.empty()       如果队列为空返回true,否则返回false
q.size()        返回队列中元素的个数
q.pop()        删除队列首元素但不返回其值
q.front()       返回队首元素的值,但不删除该元素
q.push()        在队尾压入新元素
q.back()        返回队列尾元素的值,但不删除该元素

例题

题目来源:http://acm.hdu.edu.cn/showproblem.php?pid=1285

题目描述

 Problem Description

N个比赛队(1<=N<=500),编号依次为123,。。。。,N进行比赛,比赛结束后,裁判委员会要将所有参赛队伍从前往后依次排名,但现在裁判委员会不能直接获得每个队的比赛成绩,只知道每场比赛的结果,即P1P2,用P1P2表示,排名时P1P2之前。现在请你编程序确定排名。

 

Input

输入有若干组,每组中的第一行为二个数N1<=N<=500),M;其中N表示队伍的个数,M表示接着有M行的输入数据。接下来的M行数据中,每行也有两个整数P1P2表示即P1队赢了P2队。

 

Output

给出一个符合要求的排名。输出时队伍号之间有空格,最后一名后面没有空格。

其他说明:符合条件的排名可能不是唯一的,此时要求输出时编号小的队伍在前;输入数据保证是正确的,即输入数据确保一定能有一个符合要求的排名。

 

Sample Input

4 3

1 2

2 3

4 3

 

Sample Output

1 2 4 3

 

题目大意

N个比赛队,编号依次为123,。。。。,N进行比赛,比赛结束后,裁判委员会要将所有参赛队伍从前往后依次排名,但现在裁判委员会不能直接获得每个队的比赛成绩,只知道每场比赛的结果,即P1P2,用P1P2表示,排名时P1P2之前。现在请你编程序确定排名。

其他说明:符合条件的排名可能不是唯一的,此时要求输出时编号小的队伍在前。

解题思路

如果P1P2P3赢P2,排名时P1P2之前,P3在P2之前,顺序应该为P1P3P2。在输入时,将输者加一(即【输的】++),然后按从小到大的顺序输出即可。

代码如下:

#include <stdio.h>
#include <string.h>
int map[510][510],num[510],queue[510];
 
void topo(int n)//核心内容 
{
    int i,j,m,t=0;
    for(i=0;i<n;i++)
    {
        for(j=1;j<=n;j++)//寻找[输的]=0的,并排在此时的首位 
        {
            if(num[j]==0)
            {
                m=j;
                break;
            }
        }
        queue[t++]=m;//按[输的]从小到大排序 
        num[m]=-1;
        for(j=1;j<=n;j++)
        {
            if(map[m][j])//排在首位的在此前面的减一 
                num[j]--;
        }
    }
    printf("%d",queue[0]);
    for(j=1;j<n;j++)
        printf(" %d",queue[j]);
    puts("");
}
 
int main()
{
    int n,m,i,j,x,y;
    while(~scanf("%d%d",&n,&m))
    {
        memset(map,0,sizeof(map));//初始化 
        memset(num,0,sizeof(num));
        for(i=0;i<m;i++)//输入 
        {
            scanf("%d%d",&x,&y);
            if(map[x][y]==0)
            {
                map[x][y]=1;
                num[y]++;
            }
        }
        topo(n);
    }
    return 0;
}

 

例题

题目来源:http://acm.hdu.edu.cn/showproblem.php?pid=1022

题目描述

 Problem Description

As the new term comes, the Ignatius Train Station is very busy nowadays. A lot of student want to get back to school by train(because the trains in the Ignatius Train Station is the fastest all over the world ^v^). But here comes a problem, there is only one railway where all the trains stop. So all the trains come in from one side and get out from the other side. For this problem, if train A gets into the railway first, and then train B gets into the railway before train A leaves, train A can't leave until train B leaves. The pictures below figure out the problem. Now the problem for you is, there are at most 9 trains in the station, all the trains has an ID(numbered from 1 to n), the trains get into the railway in an order O1, your task is to determine whether the trains can get out in an order O2.

 

Input

The input contains several test cases. Each test case consists of an integer, the number of trains, and two strings, the order of the trains come in:O1, and the order of the trains leave:O2. The input is terminated by the end of file. More details in the Sample Input.

 

Output

The output contains a string "No." if you can't exchange O2 to O1, or you should output a line contains "Yes.", and then output your way in exchanging the order(you should output "in" for a train getting into the railway, and "out" for a train getting out of the railway). Print a line contains "FINISH" after each test case. More details in the Sample Output.

 

Sample Input

3 123 321

3 123 312

 

Sample Output

Yes.

in

in

in

out

out

out

FINISH

No.

FINISH

 

题目大意

新学期来了,伊格内修斯火车站现在很忙。很多学生想要坐火车回学校(因为伊格内修斯火车站的火车是世界上最快的),但是又来了一个问题,火车站只有一个铁路供应所有列车停止。所以所有火车从一侧进入,从另一侧离开。对于这个问题,如果火车A第一个进入铁路,然后火车B进入铁路,在火车B离开之前,火车A不能离开,除非火车B离开。现在的问题是,最多有9列车在车站,所有的火车都有一个ID(编号从1n),火车进入铁路的订单为O1,你的任务是确定列车是否可以按照订单O2出发。

解题思路

先进后出,后进先出,典型的出入栈问题。首先一步一步的来判断是否可以根据火车进出订单来进行(可以对出入栈进行标记),如果不可以输出“no”,否则,输出“yes”,并根据标记输出进出站。

代码如下:

#include <stdio.h>
#include <stack>
#include <algorithm>
using namespace std;
int n,vis[44];
char a[22],b[22];
stack<char>q;//定义栈
int main()
{
    int i,j,k;
    while(~scanf("%d",&n))
    {
        scanf("%s%s",a,b);
        while(!q.empty())//清除栈内数据 
            q.pop();
        for(i=0,j=0,k=0;i<n;i++)
        {
            q.push(a[i]);//在栈顶压入新元素
vis[k++]=0;//进站标记为0 
            while(!q.empty()&&q.top()==b[j])//判断站中是否有火车,并且是否符合订单 
            {
                q.pop();//出站 
                j++;
                vis[k++]=1;//出站标记为1 
            }
        }
        if(q.empty())
        {
            puts("Yes.");
            for(i=0;i<n*2;i++)
                if(vis[i])
                    puts("out");
                else
                    puts("in");
        }
        else
            puts("No.");
        puts("FINISH");
    }
    return 0;
}

 

例题

题目来源:http://acm.hdu.edu.cn/showproblem.php?pid=4857

题目描述

Problem Description

糟糕的事情发生啦,现在大家都忙着逃命。但是逃命的通道很窄,大家只能排成一行。

现在有n个人,从1标号到n。同时有一些奇怪的约束条件,每个都形如:a必须在b之前。
同时,社会是不平等的,这些人有的穷有的富。1号最富,2号第二富,以此类推。有钱人就贿赂负责人,所以他们有一些好处。

负责人现在可以安排大家排队的顺序,由于收了好处,所以他要让1号尽量靠前,如果此时还有多种情况,就再让2号尽量靠前,如果还有多种情况,就让3号尽量靠前,以此类推。

那么你就要安排大家的顺序。我们保证一定有解。

 

Input

第一行一个整数T(1 <= T <= 5),表示测试数据的个数。
然后对于每个测试数据,第一行有两个整数n(1 <= n <= 30000)m(1 <= m <= 100000),分别表示人数和约束的个数。

然后m行,每行两个整数ab,表示有一个约束a号必须在b号之前。ab必然不同。

 

Output

对每个测试数据,输出一行排队的顺序,用空格隔开。

 

Sample Input

1

5 10

3 5

1 4

2 5

1 2

3 4

1 4

2 3

1 5

3 5

1 2

 

Sample Output

1 2 3 4 5

 

 

题目大意

现在大家都忙着逃命。但是逃命的通道很窄,大家只能排成一行。现在一共有n个人,从1标号到n有钱的在前边,没钱的靠后,进行排队。

解题思路

这是一道队列问题,输入时,前者排列在前边,后者靠后,并且做标记,然后根据标记进行队列排序,最后输出。

代码如下:

#include <stdio.h>
#include <string.h>
#include <queue>
#include <algorithm>
using namespace std;
#define MAX 30010
int que[MAX];
struct Node{
int to;
int next;
}A[100010];
int head[MAX];
int indegree[MAX];
int n;
 
void INPUT(){
int m,a,b,i;
memset(head,-1,sizeof(head));//初始化 
memset(indegree,0,sizeof(indegree));
scanf("%d%d",&n,&m);
for(i=0;i<m;++i)//输入数据 
{
scanf("%d%d",&a,&b);
A[i].to=a;
A[i].next=head[b];
head[b]=i;
indegree[a]++;
}
}
 
void Topo()
{
int i,j,top,k=0;
priority_queue<int>Q;//定义队列 
for(i=1;i<=n;++i)
if(indegree[i]==0)
Q.push(i);//入队 
while(!Q.empty())//判断队列是否为空 
{
top=Q.top();
Q.pop();
que[k++]=top;
indegree[top]=-1;
for(i=head[top];i!=-1;i=A[i].next)
{
indegree[A[i].to]--;
if(indegree[A[i].to]==0)
Q.push(A[i].to);
}
}
for(i=k-1;i>=0;--i)
printf(i==k-1?"%d":" %d",que[i]);
printf("\n");
}
int main()
{
int t;
scanf("%d",&t);
while(t--)
{
INPUT();
Topo();
}
return 0;
}

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值