Areas on the Cross-Section Diagram(计算面积)

本文介绍了一种使用栈数据结构来解决洪水区域面积计算问题的方法。通过解析特定的地形图,算法能够准确计算出由雨水形成的洪水区域的总面积及各部分的具体面积。此问题源于在线编程竞赛,解决方案使用Java的ArrayDeque集合类实现。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

题目链接: http://judge.u-aizu.ac.jp/onlinejudge/description.jsp?id=ALDS1_3_D

Your task is to simulate a flood damage.

For a given cross-section diagram, reports areas of flooded sections.

ALDS1_3_D.png

Assume that rain is falling endlessly in the region and the water overflowing from the region is falling in the sea at the both sides. For example, for the above cross-section diagram, the rain will create floods which have areas of 4, 2, 1, 19 and 9 respectively.

Input

A string, which represents slopes and flatlands by '/', '' and '_' respectively, is given in a line. For example, the region of the above example is given by a string "\///_//\\/_/\///__\_\///".

output

Report the areas of floods in the following format:

\(A\)

$k \quad L_1 \quad L_2 \quad ... \quad L_k $

In the first line, print the total area A of created floods.

In the second line, print the number of floods k and areas Li(i=1,2,...,k) for each flood from the left side of the cross-section diagram. Print a space character before Li.

Constraints

1≤ length of the string ≤20,000

Sample Input 1

\//

Sample Output 1

4

1 4

Sample Input 2

\///_//\\/_/\///__\_\///
Sample Output 2

35

5 4 2 1 19 9

这道题主要是对栈这种数据结构进行应用,我们使用java中的集合类ArrayDeque来实现。

首先,我们先求总面积。对输入的每个字符进行检查,当碰到""时,我们将其压入栈(压入栈的是其对应的位置);当碰到"_"时,不做任何处理;当碰到"/"时,检查栈是否为空,不为空就说明有对应的"/",弹出栈顶元素,用当前的位置减去弹出的栈顶元素,累加这些差值就是最后的面积了。

然后,对于每一个积水处的面积,我们也使用了栈,栈中存放的对象为两个元素组合的类,两个元素分别为位置和面积。位置定义为某个积水处的起始处,面积定义为这个积水处的面积。因为我们是从前向后遍历字符,所以每个积水处的面积不能一下子求出来,为此我们采取的措施为先将目前已知的积水处压入栈,对于下一个要压入栈的积水处,检查已压入栈的元素是否包含在这个要压入的积水处,如果包含,则将积水处合并,如果不包含,则直接压入栈即可。

参考代码如下:


import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.ArrayDeque;

class Pair{
    int position;
    int area;

    Pair(int pos, int area){
        this.position = pos;
        this.area = area;
    }
}

public class AreasCrossSectionDiagram {

    public static void main(String[] args) throws IOException {

        int sum = 0;
        ArrayDeque<Integer> stack1 = new ArrayDeque<>();
        ArrayDeque<Pair> stack2 = new ArrayDeque<>();

        BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
        String string = br.readLine();
        char[] chars = string.toCharArray();
        for (int i=0; i<chars.length; i++){
            if (chars[i] == '\\'){
                stack1.push(i);
            }
            else if (chars[i] == '/' && !stack1.isEmpty()){
                int j = stack1.pop();
                int temp = i-j;
                sum += temp;
                while (!stack2.isEmpty() && stack2.peek().position>j){
                    temp += stack2.pop().area;
                }
                stack2.push(new Pair(j, temp));
            }
        }

        // 将stack2反转
        ArrayDeque<Integer> stack3 = new ArrayDeque<>();
        while (!stack2.isEmpty()){
            stack3.push(stack2.pop().area);
        }

        System.out.println(sum);
        System.out.print(stack3.size());

        while (!stack3.isEmpty()){
            System.out.print(" " + stack3.pop());
        }
        System.out.println();
    }
}

参考文献:《挑战程序设计竞赛-算法和数据结构》

转载于:https://www.cnblogs.com/WanJiaJia/p/8003888.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值