题目
火车站的列车调度铁轨的结构如下图所示。两端分别是一条入口(Entrance)轨道和一条出口(Exit)轨道,它们之间有N
条平行的轨道。每趟列车从入口可以选择任意一条轨道进入,最后从出口离开。在图中有9趟列车,在入口处按照{8,4,2,5,3,9,1,6,7}的顺序排队等待进入。如果要求它们必须按序号递减的顺序从出口离开,则至少需要多少条平行铁轨用于调度?
输入格式:
输入第一行给出一个整数N
(2 ≤ N
≤105),下一行给出从1到N
的整数序号的一个重排列。数字间以空格分隔。
输出格式:
在一行中输出可以将输入的列车按序号递减的顺序调离所需要的最少的铁轨条数。
输入样例:
9
8 4 2 5 3 9 1 6 7
输出样例:
4
代码如下:
#include<iostream>
#include<set>
using namespace std;
int main()
{
int N,t;
cin>>N;
set<int>s;
s.insert(0);
for(int i=0;i<N;i++)
{
cin>>t;
if(t<*s.rbegin())
{
s.erase(*(s.upper_bound(t)));
}
s.insert(t);
}
cout<<s.size()-1;
return 0;
}
思路分析:
每当有一辆火车入站时,我们查询是否已经有比它序号要大的火车在等待,并且这辆等待的火车后面没有其他火车阻塞。如果找到了,那我们就把这辆车加入到查询到的列车的队列中,并把查询到的列车从队列中删除。删除的作用是:下次查询等待的列车就不会查询到了尾部有其他列车阻塞的列车了,并且每一辆在集合中的火车都可以代表着一条独立的轨道,也就是说集合中的每一个数据都代表着一轨道的火车。如果没有查询到有比新加入的火车序号大的列车,那么直接把该火车加入集合,相当于增加了一条轨道。循环至火车全部入站,集合的个数就是火车需要的轨道数量。注意:在开头我们插入了一个零号火车,这辆火车会独立占有一条轨道,因此,我们输出结果时,需要减去它。
数据结构set
set(集合)是一个根据元素键值自动排序的数据结构,在内部元素为int类型时默认为降序排序。
-
rbegin() ; 返回逆序迭代器。简而言之:rbegin() ; 将会返回指向容器最后一个元素的指针。
-
upper_bound(t) ; 返回的是在容器中值排在 t 元素的值后的第一个元素的指针。
举个栗子:
集合s中的元素为{1,5,6,11,20};
此时s.rbegin()返回的结果就是指向20的指针,s.upper_bound(5)返回的结果就是指向6的指针。如果想要得到指向5的指针可以使用:lower_bound,即s.upper_bound(5)返回的就是指向5的指针。注意:如果 t 元素不在集合中,那么lower_bound和s.upper_bound的返回结果都是一样的。如:s.upper_bound(4)的结果就为5,s.lower_bound(4)的结果也为5。