第十五届北京师范大学程序设计竞赛决赛 K. Keep In Line【模拟】

本文介绍了一种算法,用于解决一个有趣的问题:通过模拟队列操作来计算在一个动态变化的队列中,有多少人没有插队。文章详细解释了解决方案的思路,并提供了完整的AC代码实现。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

K. Keep In Line

Time Limit: 2000ms
Memory Limit: 262144KB
64-bit integer IO format:  %lld      Java class name:  Main

又到饭点了,SK同学靠着惯性走到了食堂,但长长的队伍顿时让他失去了食欲。突然,他注意到某个窗口前的队伍里明显存在插队的现象,于是他默默记录下了同学们进队和出队的变化。

对于进队,SK同学只知道队伍里多了一个人,并不知道新来的人是老老实实站到了队尾还是插到了队伍里的某个位置;对于出队,SK同学能确定是队伍里站在最前面的人出队了。

初始时队伍为空,给出n条队伍进出的信息,保证已经出队的同学不会再入队,并且最终队伍也为空,现在SK同学想知道有多少不插队的好同学。

Input

第一行是一个正整数T(\leq 5),表示测试数据的组数,

对于每组测试数据,

第一行是一个整数n(1\leq n \leq 100000),表示这个队伍进出的信息数,

接下来n行,每行是两个字符串Opt Name,其中Opt为"in"代表进队,"out"代表出队,Name为进队或出队的人的名字,

所有信息按照时间顺序给出,名字由英文字母和阿拉伯数字组成,长度不超过10,保证每个人的名字各不相同。

Output

对于每组测试数据,输出一行,包含一个整数,表示不插队的人数。

Sample Input

1
6
in quailty
in hwq1352249
out hwq1352249
in zhuaiballl
out quailty
out zhuaiballl

Sample Output

2

思路:


按照题意模拟。

我们维护一个队列,in操作直接在队尾加入这个人,out操作先将之前插队了的在队头的所有元素都去掉,然后再判断当前队头和out操作这个人是否相等,如果相等,那么output++

否则标记这个人在队列中是插队的,将其置为队内无用元素即可。


Ac代码:


#include<stdio.h>
#include<string.h>
#include<queue>
#include<map>
#include<iostream>
using namespace std;
int vis[1008000];
int main()
{
    int t;
    scanf("%d",&t);
    while(t--)
    {
        int n;
        scanf("%d",&n);
        int tot=0;
        int cnt=1;
        queue<int >que;
        map<string,int >s;
        memset(vis,0,sizeof(vis));
        for(int i=0;i<n;i++)
        {
            char op[45];
            char name[45];
            scanf("%s%s",&op,&name);
            if(s[name]==0)
            {
                s[name]=cnt;
                cnt++;
            }
            if(op[0]=='i')
            {
                que.push(s[name]);
            }
            else
            {
                while(!que.empty())
                {
                    int u=que.front();
                    if(vis[u]==1)que.pop();
                    else break;
                }
                if(que.size()>0&&que.front()==s[name])tot++,que.pop();
                else vis[s[name]]=1;
            }
        }
        printf("%d\n",tot);
    }
}










评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值