火车站的列车调度铁轨的结构如下图所示。
两端分别是一条入口(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
解法思路:本题一开始对于题意理解不清,导致做了很多无用功。之后打算用多重队列来做,但很遗憾本题数据过大,导致仅得到18分。后参考网上大佬的代码,发现有一个特别巧妙的set做法,看完啧啧称赞,代码真是短小精悍!
先上我这个废物代码。。。。:
#include<iostream>
#include<cstring>
#include<algorithm>
#include<queue>
#include<map>
#include<math.h>
using namespace std;
vector<queue<int>> a;//队列动态数组
const int N=100010;
int A [N];
int main()
{
int n;
cin>>n;
a.resize(10000);//为数组预分配空间
for(int i=0;i<n;i++)
cin>>A[i];
int length=0;
int t=n;
for(int i=0;i<n;i++)
{ int gap=0x3f;
int index=-1;
int flag=0;
int flag1=0;
for(int j=0;j<length;j++)
{
if (a[j].empty() && A[i] == t)
{ flag1=1;
flag=1;
t--;
break;
}
if(!a[j].empty()&&a[j].back()>A[i])//取队尾元素,注意该处取的是最近一次插入的元素,故判断队列是否为空很关键哦!!!
{
if(a[j].back()-A[i]<gap)
{ flag=1;
gap=a[j].back()-A[i];
index=j;
}
}
}
if(flag1)
break;
if(!flag)
{
length++;
a[length-1].push(A[i]);
}
if(flag)
{
a[index].push(A[i]);
}
int flag2=1;
while(flag2)
{ flag2=0;
for (int z = 0; z < length; z++)
{ if(!a[z].empty()) {
if (a[z].front() == t) {
a[z].pop();
t--;
flag2 = 1;
}
}
}
}
}
cout<<length;
return 0;
}
参考完大佬代码后写的:
#include<iostream>
#include<cstring>
#include<algorithm>
#include<queue>
#include<map>
#include<math.h>
#include<set>
using namespace std;
int main()
{
set<int>t;
int n;
cin>>n;
for(int i=0;i<n;i++) {
int a;
cin >> a;
set<int>::iterator it = t.lower_bound(a);//背诵!!!!
if (it != t.end())
{
t.erase(it);
t.insert(a);
}
else
{
t.insert(a);
}
}
cout<<t.size();
return 0;
}
人和人的差距有时比人和^(* ̄(oo) ̄)^的差距都大