標籤:size names 編號 tput color 高度 top sample har
codevs 1531 山峰題目描述 Description
Rocky山脈有n個山峰,一字排開,從西向東依次編號為1, 2, 3, ……, n。每個山峰的高度都是不一樣的。編號為i的山峰高度為hi。
小修從西往東登山。每到一座山峰,她就回頭觀望自己走過的艱辛曆程。在第i座山峰,她記錄下自己回頭能看到的山峰數si。
何謂“能看到”?如果在第i座山峰,存在j<k<i,hj<hk,那麼第j座山峰就是不可見的。除了不可見的山峰,其餘的山峰都是可見的。
回家之後,小修把所有的si加起來得到S作為她此次旅行快樂值。現在n座山峰的高度都提供給你了,你能計算出小修的快樂值嗎?
輸入描述 Input Description
第一行一個整數n(n<=15000)。
第i+1(1<=i<=n)行是一個整數hi(hi<=109)。
輸出描述 Output Description
僅一行:快樂值。
範例輸入 Sample Input
5
2
1
3
5
9
範例輸出 Sample Output
5
資料範圍及提示 Data Size & Hint
說明:s1=0, s2=1, s3=2, s4=1, s5=1。
維護一個單調遞減的棧stack[]。
設當前元素為x,棧頂元素為k,棧頂指標為top,ans為到目前為止所能看到的山峰總數
如果x<k,ans+=top,x入棧。這座山比棧頂存的山低,那麼由於棧從底部到頂部遞減,所以此時棧內有幾座山,就能看到幾座山。
如果x=k,ans+=top,這座山和棧頂的山高度相同,設棧頂能看到y座山,在這座山就能看到y+1座山(加上的是棧頂這座山),也就是棧內所有的山。
如果x>k,1、ans+=top這座山比棧頂的山高,由於棧從棧底到棧頂單調遞減,所以這座山比棧內所有的山高,可以看到所有的山。
2、由於這座山很高,所以會遮擋後面的視線,所以要維護棧的單調性,也就是從棧頂開始,如果這座山比棧頂的山高,棧頂退棧,直至退到這座山比棧頂的山低為止,x再入棧。
由此可以看出,對於每一個位置,都可以看到當前棧內所有的山,所以直接枚舉,ans+=top
#include<cstdio>#include<iostream>using namespace std;int stack[15001],top;int n,ans,x;int init()//讀入最佳化,也可以直接輸入 { int x=0;char c=getchar(); while(c<‘0‘||c>‘9‘) c=getchar(); while(c>=‘0‘&&c<=‘9‘) {x=x*10+c-‘0‘;c=getchar();} return x;}int main(){ n=init(); for(int i=1;i<=n;i++) { x=init(); ans+=top; if(x<stack[top-1]) stack[top++]=x;//這座山比棧頂的山低 else if(x>stack[top-1])//這座山比棧頂的山高 { while(top&&x>stack[top-1]) top--;//維護單調性 stack[top++]=x; } } printf("%d",ans); }
codevs 1531 山峰