1. 程式人生 > 其它 >洛谷P3434 [POI2006]KRA-The Disks題解

洛谷P3434 [POI2006]KRA-The Disks題解

此乃本蒟蒻做出的第一道藍題 感覺好簡單

感覺就是黃題難度

題目轉送門

正文開始

前置思路

維護一個序列 \(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;
}

完結撒花 (。・∀・)ノ花花花