【20171006】某书某题:ALDS1_3_D: Areas on the Cross-Section Diagram 栈的巧妙应用
题目描述
计算积水的面积。
输入
1行,用”\”和”/”表示斜面,用”_”表示平地。
输出
第1行输出总横截面积,第2行输出积水数量和各积水处的横截面积。
实现
示例输入
\\///\_/\/\\\\/_/\\///__\\\_\\/_\/_/\
示例输出
35
4 2 1 19 9
思路
利用栈的特性,鉴于地形的特殊输入方式,类比于“括号匹配”,考虑每一个'/'对应一个'\',并算出此两符号直线上的积水横截面积:
(每种颜色代表着一次‘\''/'匹配)
那么对于第一问,直接建立栈stack1,将'\'压栈,对所有匹配面积求和totals即可
对于第二问,我们可以另建立一个二元栈stack2,栈中存储当前每个“水坑”(即'\''/'匹配)的左端点&面积,每当新的“水坑”能够覆盖旧水坑的时候,就从stack2中将被覆盖的旧水坑弹出(旧水坑一定在栈顶,因为你无法跳过一个水坑来覆盖它两边的水坑:对于有序水坑(1,2),(3,4),(5,6),新水坑(0,8)无法仅覆盖(1,2),(5,6)而不覆盖(3,4)),将旧水坑面积加入新“水坑”面积中即可。
代码——如有错误请指出
#include <stdio.h> #define MAXN 50 int main() { int s1[MAXN]={0},s2[MAXN][2]={0}; int top1,top2; top1=top2=0; int totalS=0; int i=1,j,k,partS; char ch; while(scanf("%c",&ch)!=EOF) { if(ch=='\\') { s1[top1++]=i; } else if(ch=='/') { partS=i-s1[top1]; totalS+=partS; k=-1; for(j=0;j<=top2;j++) { if(s1[top1]<s2[j][0])//s2[j]表示的积水在s1[top1]内 { if(k==-1) { k=j; s2[k][0]=s1[top1]; } partS+=s2[j][1]; } } s2[k][1]=partS; top2=k; } i++; } return 0; }
stack1 | 1 | 2 | 3 | ||||||||||||||
3 | 6 | totals+= 6-3-1+2×0.5 = 6-3 = 3 | |||||||||||||||
stack1 | 1 | 2 | |||||||||||||||
2 | 7 | totals+= 7-2 = 5 | |||||||||||||||
stack1 | 1 | 10 | 11 | ||||||||||||||
11 | 12 | totals+= 12-11 = 1 | |||||||||||||||
. | . | . | . | . | . | . | . | . | . | . | . | . | . | . | . |
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】凌霞软件回馈社区,博客园 & 1Panel & Halo 联合会员上线
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】博客园社区专享云产品让利特惠,阿里云新客6.5折上折
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步