北大OJ百练——4074:积水量(C语言)
前言:
最近感覺算法是一個很重要的東西,于是又把以前的OJ撿起來做做了,看到一題叫做積水量的題目,通過率是100%,雖然說是沒有什么挑戰,不過很久沒寫OJ了,讓自己進入狀態也不錯的。
描述:
凹凸不平的地面每當下雨的時候總會積水。假設地面是一維的,每一塊寬度都為1,高度是非負整數,那么可以用一個數組來表達一塊地面。例如[0,1,0,2,1,0,1,3,2,1,2,1]可以用來表示下圖地面:
輸入
第一行是一個整數m,表示有m組試樣例,不超過100。接下來m塊,每塊第一行是一個正整數n,表示地面總寬度(數組長度),不超過20000。
接下來一行是n個整數,用空格隔開,表示地面高度。
輸出
對于每組輸入,輸出一個整數表示積水量。
源代碼示例:
#include <stdio.h> #define MAX 20000 #define HAD_WALL 1 #define NO_WALL 0 int calWater(int w[], int n) {int i, j;int max, flag;int part, sum;// 找出w[]中最大的一個數 for (i = 0, max = 0; i < n; ++i){if(w[i] >= max) max = w[i];} // 從下往上依次遍歷for (i = 0, sum = 0; i < max; ++i){// 對每一趟進行遍歷for(j = 0, flag = NO_WALL, part = 0; j < n; ++j){ if(w[j] > i && !flag) // 沒有墻,并且遇到了一面墻,設置flag標志為IS_WALL{flag = HAD_WALL;} if(w[j] <= i && flag) // 有墻,并且此點不是墻,這一小段的緩沖距離part+1{++part;}// 有墻,并且遇到了結束墻,就這個墻和前一個墻之間的距離疊加,緩沖距離歸零if(w[j] > i && flag){sum += part;part=0;} }part=0; // 遍歷完一趟,緩沖距離清零}return sum; } int main( ) {int m;int n, i;int floor[MAX];scanf("%d", &m);while(m--){scanf("%d", &n); for (i = 0; i < n; ++i){scanf("%d", &floor[i]);} // 計算積水量int s = calWater(floor, n);printf("%d\n", s);}return 0; }當下過雨后,地面就會積水,上圖中藍色的區域就是積水區域。現在給你一個數組表示地面,求下過雨后這塊地面有多少積水量(假設不蒸發、不滲透)。
解析:
當同學們看到這題目的時候,可能會被題目中的圖所迷惑,以為應該按列來計算。我也是,當然這只是第一感覺,后來一想,按列來算不可能,這樣還必須記錄之前那個有障礙物的地方,還有它的高度,很麻煩。
其實我們的想法很簡單,首先我們要明確這題應該從行上來考慮,而且還是要從下往上來計算,因為障礙物是只要上面有,下面的一格必定會有障礙物。還有就是我們要知道只有在障礙物和障礙物之間才可能會有積水產生,那么,我們就要去確定障礙物的邊界問題。
我們可以在第一次遇到障礙物的時候,設置一個標記參數為已經有了障礙物,當下次我們再一次遇到障礙物的時候,那么這兩個相鄰的障礙物之間的部分正是我們想要的。最后再把它們累加起來,就大功告成了。。。
下面貢獻出我的代碼,當然我知道還有大牛能寫出更牛的代碼,求輕噴。。。
原題地址:
原題網址接連
總結
以上是生活随笔為你收集整理的北大OJ百练——4074:积水量(C语言)的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: Android开发中如何设置不显示标题和
- 下一篇: 北大OJ百练——4073:最长公共字符串