1. 程式人生 > >【題解】砍樹

【題解】砍樹

如果 樹的高度 close queue time isp 題解 push struct

題目描述

為了在農場的一塊土地上種奶牛吃的草,Farmer John必須要把前面的N棵樹砍掉,這些樹緊密地排成一條直線,並且用1-N編號標識,每一棵樹都有自己的高度Hi(1≤Hi≤10000)。

Farmer John想用炸彈來摧毀這些樹,這種炸彈除了能摧毀安裝了炸彈的那棵樹以外還能傳遞壓倒兩邊矮於這一棵樹的所有鄰近樹,直到遇到一棵不低於這一棵樹的樹為止。

例如:一排樹的高度如下:1 2 5 4 3 3 6 6 2,如果Farmer John在第三棵樹上裝炸彈(高度為5),那麽第二棵樹也同樣給壓倒(高度為2<5),第一棵樹也同樣倒下(高度為1<2),再來看另一邊第四棵樹(高度為4<5)和第五棵樹(高度為3<4)同樣也給壓倒。剩下的狀態為:× × × × × 3 6 6 2,接下來在第七和第八棵樹上安裝炸彈就可以把剩下的樹毀掉。

請你幫助Farmer John利用最少的炸彈把這些樹毀掉。

輸入格式

第一行,一個整數N(1≤N≤50000);

第二行至第N+1行,包含各棵樹的高度Hi。

輸出格式

第一至第?行,每一行為一個整數,代表安裝炸彈的樹的編號,按照升序輸出。

輸入樣例

9

1

2

5

4

3

3

6

6

2

輸出樣例

3

7

8

題解

容易想到,從最高的樹開始炸即可。

技術分享圖片
#include <iostream>
#include 
<cstdio> #include <algorithm> #include <queue> #define MAXN 50001 using namespace std; int n; int a[MAXN]; struct node { int hei; int idx; }b[MAXN]; bool cmp(node a, node b) { return a.hei > b.hei;// 從高的樹開始炸 } priority_queue<int, vector<int>, greater<int
> > q;// 答案從小到大排序 int main() { scanf("%d", &n); for(register int i = 1; i <= n; i++) { scanf("%d", &a[i]); b[i].hei = a[i]; b[i].idx = i; } sort(b + 1, b + 1 + n, cmp); for(register int i = 1, c; i <= n; i++) { if(a[b[i].idx]) { c = a[b[i].idx]; for(register int j = b[i].idx - 1; j >= 1; j--) {// 壓到左邊的數 if(a[j] < c) { if(a[j]) { c = a[j]; a[j] = 0; } else break; } else break; } c = a[b[i].idx]; for(register int j = b[i].idx + 1; j <= n; j++) {//壓倒右邊的數 if(a[j] < c) { if(a[j]) { c = a[j]; a[j] = 0; } else break; } else break; } q.push(b[i].idx); a[b[i].idx] = 0; } } while(!q.empty()) { printf("%d", q.top()); q.pop(); if(!q.empty()) putchar(\n); } return 0; }
參考程序

【題解】砍樹