洛谷P3434 [POI2006]KRA-The Disks題解
阿新 • • 發佈:2021-06-18
此乃本蒟蒻做出的第一道藍題 感覺好簡單
感覺就是黃題難度
正文開始
前置思路
維護一個序列 \(f\),使 \(f_i=\min(r_i,f_{i-1})\),\(f_1=r_1\)
這樣 \(f_i\) 就表示 \(\min(r_1,r_2,r_3\cdots r_i)\)
\(f_i\) 也就是 \(r_1\)~\(r_i\) 最窄的管子的直徑。
對於每個盤子,在放入管子的時候(能放的情況)都是由上到下(落下)進入管道,在遇到盤子阻擋或比自己窄的管子時才會停下來。
程式碼思路
知道了從第 \(1\) 層到第 \(i\) 層(沒有盤子阻擋的最下層)最小的直徑,從下往上找,直到找到最小直徑能放下第 \(j\)
一共只用迴圈一遍,時間複雜度是 \(O(n)\)
從下往上找,找到一個滿足條件的就換下一個(指盤子),直到最上方(塞不下了)。
如果塞不下了就輸出 \(0\)。
程式碼
#include<iostream> #include<queue> using namespace std; int a[300005]; int main() { int n,m,ans,k; cin>>n>>m>>a[1]; for(int i=2;i<=n;i++) cin>>a[i],a[i]=min(a[i],a[i-1]);//上方最小值 k=n;//k用來儲存目前是第幾層 for(int i=1;i<=m;i++) { int x; cin>>x; while(x>a[k--]);//找到能塞下的一層 if(k==0)//塞不下了 { cout<<0; return 0; } } cout<<k+1;//最後一次多減了一,補回來 return 0; }
完結撒花 (。・∀・)ノ花花花