• 横截面图


    横截面图

    Time Limit : 1 sec  Memory Limit : 131072 KB

    Description

    你的任务是模拟洪水灾害。 对于给定的横截面图,报告淹没区域的横截面积。

    假设该地区持续降雨,从该地区溢出的多余雨水将流入两侧的海水中。例如,对于上面的横截面图,降雨将引发洪水,积水处的横截面积从左至右分别为4、2、1、19和9。

    Input

    一个字符串,分别用' / ',' '和' _ ' 表示斜坡和平地,用一行表示。例如,上面示例的区域由字符串“ \ /// _ / / \\ / _ / \ /// __ \ _ \ / _ / _ / “表示。

    output

    第一行输出该区域积水处的横截总面积A(整数)。 第二行从左至右按顺序输出积水处的数量k,以及各积水处的横截面积 Li(i=1,2,...,k)。

    Constraints 

    1 ≤ 字符串长度 ≤ 20000

    Sample Input 1

    \//

    Sample Output 1

    4

    1 4

    Sample Input 2

    \///\_//\\/_/\///__\\_\/_/_/

    Sample Output 2

    35

    5 4 2 1 19 9

    分析:

    由淹没区域可以想到 ‘’ 与 '/' 的配对。

    此题比较特别的是如何组成一整个被水淹没的区间?答案是将所有配对的区间中 相互包含的区间合并。

    如何合并呢?可以知道大区间所包含的小区间必定比大区间先入栈,则可以依此合并。

    如何计算横截面积?所有配对的‘’与'/'之间形成的横截面都为梯形或三角形,把问题分解为多个小问题来解答。

    放代码:

    #include<cstdio>
    #include<cstring>
    #include<iostream>
    #include<stack>
    using namespace std;
    struct area
    {
        int begin,end;
        bool fl;
    };
    
    
    int main()
    {
        freopen("areas.in","r",stdin);
        freopen("areas.out","w",stdout);
        stack <int> stack;
        area k[20050];
        for(int i = 0;i<= 20000;i++)
            k[i].fl = 0;
        int order,ans[20050];
        memset(ans,0,sizeof(ans));
        string s;
        cin>>s;
        int top = -1,j;
        bool rise = 1;
        for(int i = 0; i < s.size(); i++)
        {
            if(s[i] == '\')stack.push(i);
            if(s[i] == '/' && !stack.empty())
            {
                order = stack.top();
                stack.pop();
                k[++top].begin = order;
                k[top].end = i;
            }
        }
        
        int i = top,x,y;
        while(i >= 0)
        {
            j = i;
            x = k[i].begin, y = k[i].end;
            k[i].fl = 1;
            
            while(k[i].begin >= x && k[i].end <= y)
            {
                ans[j] += k[i].end-k[i].begin;
                i--;
                if(i < 0)break;
            }
        }
        
        long long int anssum = 0,num=0;
        for(int i=0;i<=top;i++)
        {
            if(k[i].fl)
            anssum += ans[i],num++;
        }
        cout<<anssum<<endl<<num<<' ';
        for(int i=0;i<=top;i++)
        {
            if(k[i].fl)
            cout<<ans[i]<<' ';
        }
        
        fclose(stdin);
        fclose(stdout);
        return 0;
    }
  • 相关阅读:
    遗传算法(Genetic Algorithm, GA)及MATLAB实现
    CCF CSP 201809-2 买菜
    PAT (Basic Level) Practice (中文)1008 数组元素循环右移问题 (20 分)
    PAT (Basic Level) Practice (中文)1006 换个格式输出整数 (15 分)
    PAT (Basic Level) Practice (中文)1004 成绩排名 (20 分)
    PAT (Basic Level) Practice (中文)1002 写出这个数 (20 分)
    PAT (Advanced Level) Practice 1001 A+B Format (20 分)
    BP神经网络(原理及MATLAB实现)
    问题 1676: 算法2-8~2-11:链表的基本操作
    问题 1744: 畅通工程 (并查集)
  • 原文地址:https://www.cnblogs.com/Cindy-Chan/p/11185479.html
Copyright © 2020-2023  润新知