扔盤子 (Ver. I)
阿新 • • 發佈:2021-01-03
技術標籤:Data Structure
題解
- 如果按照常規的暴力解法會TLE,如程式碼1所示。
- 優化方法1:相鄰的兩個凹槽如果上層凹槽寬度小於等於下層凹槽寬度,則下層凹槽的寬度無論是多少都對扔盤子沒有影響,盤子只可能落到上層或者下層以下。所以可以在一開始就預處理使得這種情況下下層的寬度改為等於上層的寬度,使得整個井的寬度從上到下遞減。
題目
問題 E: 扔盤子 (Ver. I)
時間限制: 1 Sec 記憶體限制: 128 MB
提交: 21 解決: 6
[提交][狀態][討論版]
題目描述
有一口井,井的高度為N,每隔1個單位它的寬度有變化。現在從井口往下面扔圓盤,如果圓盤的寬度大於井在某個高度的寬度,則圓盤被卡住(恰好等於的話會下去)。
盤子有幾種命運:1 、掉到井底。2、被卡住。3、落到別的盤子上方。
盤子的高度也是單位高度。給定井的寬度和每個盤子的寬度,求最終落到井內的盤子數量。
如圖井和盤子資訊如下:
井:5 6 4 3 6 2 3
盤子:2 3 5 2 4
最終有4個盤子落在井內。
輸入
第1行:2個數N, M中間用空格分隔,N為井的深度,M為盤子的數量(1 <= N, M <= 50000)。
第2 - N + 1行,每行1個數,對應井的寬度Wi(1 <= Wi <= 10^9)。
第N + 2 - N + M + 1行,每行1個數,對應盤子的寬度Di(1 <= Di <= 10^9)
輸出
輸出最終落到井內的盤子數量。
樣例輸入
7 5
5
6
4
3
6
2
3
2
3
5
2
4
樣例輸出
4
程式碼(TLE)
#include <iostream>
using namespace std;
int main(void)
{
int i, num1, num2;
cin>>num1>>num2;
int a[num1], b[num2];
for(i=0; i<num1; i++)
cin>>a[i];
for(i=0; i<num2; i++)
cin>>b[i];
int count = 0;
int temp = 0;
while(num1 && temp!=num2)
{
for(i=0; i<num1; i++)
{
if(a[i]<b[temp])
break;
}
num1 = i-1;
count++;
temp++;
}
cout<<count<<endl;
}
程式碼(AC)
#include <iostream>
using namespace std;
int main(void)
{
int i, j, num1, num2;
cin>>num1>>num2;
int a[num1], b[num2];
for(i=0; i<num1; i++)
{
cin>>a[i];
if(i && a[i]>a[i-1])//預處理
a[i] = a[i-1];
}
for(i=0; i<num2; i++)
cin>>b[i];
int count = 0;
for(i=0; i<num2; i++)
{
while(num1 && b[i]>a[num1-1])
num1--;
if(num1)
{
num1--;
count++;
}
else
break;
}
cout<<count<<endl;
}