PTA 7-2 列車排程(25 分) 思路+超時程式碼+正確程式碼
火車站的列車排程鐵軌的結構如下圖所示。
兩端分別是一條入口(Entrance)軌道和一條出口(Exit)軌道,它們之間有N
條平行的軌道。每趟列車從入口可以選擇任意一條軌道進入,最後從出口離開。在圖中有9趟列車,在入口處按照{8,4,2,5,3,9,1,6,7}的順序排隊等待進入。如果要求它們必須按序號遞減的順序從出口離開,則至少需要多少條平行鐵軌用於排程?
輸入格式:
輸入第一行給出一個整數N
(2 ≤ N
≤10^5),下一行給出從1到N
的整數序號的一個重排列。數字間以空格分隔。
輸出格式:
在一行中輸出可以將輸入的列車按序號遞減的順序調離所需要的最少的鐵軌條數。
輸入樣例:
9
8 4 2 5 3 9 1 6 7
輸出樣例:
4
思路:
輸入n,容器空直接進,不空跟最大值maxn比較,如果比maxn大,就放進容器,否則找比n大而且最接近的數num,用n覆蓋num。最後輸出容器元素個數。
剛開始自己按照這思路寫的,思路是正確的,但用的Vector容器,在找num時加了一層迴圈,時間複雜度為O(n^2),提交執行超時。
下面是第一次提交的錯誤程式:
#include <bits/stdc++.h>
#include <stdlib.h>
#include <stdio.h>
using namespace std;
int GetMinn(vector<int> &v,vector<int>::iterator &iter)
{
int i;
for(iter=v.begin(),i=*iter; iter!=v.end(); iter++)
if(i>*iter)
i=*iter;
return i;
}
void SetMinn(vector<int> &v,int n,int minn)
{
vector<int>::iterator iter;
int i=0;
for(iter=v.begin(); iter!=v.end(); iter++,i++)
if(*iter==minn)
v[i]=n;
}
int GetMaxn(vector<int> &v)
{
int i;
vector<int>::iterator iter;
for(iter=v.begin(),i=*iter; iter!=v.end(); iter++)
if(i<*iter)
i=*iter;
return i;
}
void GetMatch(vector<int> &v,int &n)
{
vector<int>::iterator iter1,iter2;
int i=n,j=1,k;
for(iter1=v.begin(); iter1!=v.end(); iter1++,j++)
{
if(i>abs(*iter1-n))
{
i=abs(*iter1-n);
iter2=iter1;
k=j;
}
}
v[k]=n;
}
int main()
{
vector<int> v;
vector<int>::iterator iter1,iter2;
int minn,maxn;
int num,n;
cin>>num>>n;
v.push_back(n);
num--;
for(int i=0; i<num; i++)
{
cin>>n;
minn=GetMinn(v,iter2);
maxn=GetMaxn(v);
if(n<minn)
SetMinn(v,n,minn);
else if(n>maxn)
v.push_back(n);
else
GetMatch(v,n);
}
/*for(iter1=v.begin(); iter1!=v.end(); iter1++)
cout<<*iter1<<endl;*/
cout<<v.end()-v.begin();
return 0;
}
後來重新用set寫,Set不但自動排序,裡面還有upper_bound(num)函式,查詢與num最接近的比num大的數,省去了內層迴圈,時間複雜度縮小到了O(n)。
正確程式碼如下:
#include <bits/stdc++.h>
using namespace std;
int main()
{
int num,n;
cin>>n;
set<int> s;
for(int i=0;i<n;i++)
{
cin>>num;
if(s.upper_bound(num)!=s.end())
s.erase(s.upper_bound(num));
s.insert(num);
}
cout<<s.size();
return 0;
}