zoukankan      html  css  js  c++  java
  • 横截面图

    横截面图

    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;
    }
  • 相关阅读:
    [转] SQL Server中的行列转换问题
    【原】Sql中时间处理函数 DateAdd & DateDiff
    [转] 为GridView删除添加确认对话框
    【转】jQuery入门指南教程
    [原] Excel(VBA)中数据的非科学记数法显示
    【原】IP地址存储问题
    【转】 asp.net数据导出EXCEL
    【原】有线通设定
    【原】 VS2005/VWD2005调试错误“无法附加,绑定句柄无效”的解决
    [原] Excel中计算2个日期间的时间间隔
  • 原文地址:https://www.cnblogs.com/Cindy-Chan/p/11185479.html
Copyright © 2011-2022 走看看