luogu P1318 積水面積
阿新 • • 發佈:2018-11-06
這道題有點繞,其實想明白很簡單,想不明白你就會像我一樣很早很早之前就看過這題,完全不會,看過很多次,完全沒思路,今天又突然想起這道題,然而還是不會。。。
直到睡覺前突然間有了靈感三分鐘打完程式碼,過了樣例交上結果A了;
題目描述
一組正整數,分別表示由正方體迭起的柱子的高度。若某高度值為x,表示由x個正立方的方塊迭起(如下圖,0<=x<=5000)。找出所有可能積水的地方(圖中藍色部分),統計它們可能積水的面積總和(計算的是圖中的橫截面積。一個立方體的位置,為一個單位面積)。
如圖:柱子高度變化為 0 1 0 2 1 2 0 0 2 0
圖中藍色部分為積水面積,共有6個單位面積積水。
輸入輸出格式
輸入格式:
兩行,第一行n,表示有n個數(3<=n<=10000)。第2行連續n個數表示依次由正方體迭起的高度,保證首尾為0。
輸出格式:
一個數,可能積水的面積。
輸入輸出樣例
輸入樣例#1: 複製
10
0 1 0 2 1 2 0 0 2 0
輸出樣例#1: 複製
6
每一個點能不能有積水在於在同一高度它的左右是不是都有柱子,即左右都有比該點高的柱子,則該處可以有積水,可以積水的地方為左邊最大值和右邊最大值的最小值與該點的差值,就正著求出每個點之前出現過的最大值(柱子最高值),反著再求一遍每個點之後的最大值(柱子最高值),再迴圈一遍求出差值求和即可。
#include<iostream> #include<cstdio> #include<algorithm> using namespace std; inline int read(){ int x = 0; int f = 1; char c = getchar(); while(c<'0'||c>'9'){ if(c == '-')f = -f; c = getchar(); } while(c<='9'&&c>='0'){ x = x * 10 + c - '0'; c = getchar(); } return x*f; } int l,r,n,ans; int maxx[5000000],minn[5000000],pic[5000000]; int main(){ n = read(); for(int i = 1; i<=n; i++)pic[i] = read(); for(int i = 1; i<=n; i++){ maxx[i] = max(maxx[i - 1],pic[i]); } for(int i = n; i>=1; i--){ minn[i] = max(minn[i+1],pic[i]); } for(int i = 1; i<=n; i++){ ans += max(0,min(maxx[i],minn[i]) - pic[i]); } cout<<ans; return 0; }