又到饭点了,SK同学靠着惯性走到了食堂,但长长的队伍顿时让他失去了食欲。突然,他注意到某个窗口前的队伍里明显存在插队的现象,于是他默默记录下了同学们进队和出队的变化。
对于进队,SK同学只知道队伍里多了一个人,并不知道新来的人是老老实实站到了队尾还是插到了队伍里的某个位置;对于出队,SK同学能确定是队伍里站在最前面的人出队了。
初始时队伍为空,给出n条队伍进出的信息,保证已经出队的同学不会再入队,并且最终队伍也为空,现在SK同学想知道有多少不插队的好同学。
第一行是一个正整数T(≤ 5),表示测试数据的组数, 对于每组测试数据, 第一行是一个整数n(1≤ n ≤ 100000),表示这个队伍进出的信息数, 接下来n行,每行是两个字符串Opt Name,其中Opt为"in"代表进队,"out"代表出队,Name为进队或出队的人的名字, 所有信息按照时间顺序给出,名字由英文字母和阿拉伯数字组成,长度不超过10,保证每个人的名字各不相同。
对于每组测试数据,输出一行,包含一个整数,表示不插队的人数。
1 6 in quailty in hwq1352249 out hwq1352249 in zhuaiballl out quailty out zhuaiballl
2
//使用一个双端队列保存元素的入队顺序,方便在队首出队元素和在队尾存放元素 //如果是In,直接将元素保存在双端队列的末尾 //如果是out,且出队元素位于队首,直接出队 // 如果出队元素不位于队首,那么使用哈希表标记该元素已经被删除,等到真 // 正扫描到这个元素的时候,再真正将这个元素移除。 //时间复杂度O(n) #include <iostream> #include <string> #include <queue> #include <unordered_map> using namespace std; int main(){ int T; cin >> T; while (T--){ int n; cin >> n; string Opt, Name; deque<string> inOrder; unordered_map<string, bool> outmap; int count = 0; for (int i = 0; i < n; i++){ cin >> Opt >> Name; if (Opt == "in"){ inOrder.push_back(Name); } else{ if (Name == inOrder[0]){ inOrder.pop_front(); } else{ while (outmap[inOrder[0]]){ inOrder.pop_front(); } if (Name == inOrder[0]) inOrder.pop_front(); else{ outmap[Name] = true; count++; } } } } cout << n / 2 - count << endl; } return 0; }
#include<queue> #include<map> #include<stdio.h> #include<string> #include<iostream> using namespace std; int main(){ int T,n,i; for(cin>>T;T--;){ int res=0; map<string,int> book; queue<string> Q; for(cin>>n;n--;){ string x,y; cin>>x>>y; if(x=="in") Q.push(y),book[y]=1; else{ while(book[Q.front()]==0) Q.pop(); string head=Q.front(); if(y==head) res++,Q.pop(); else book[y]=0; } } printf("%d\n",res); } }