zoukankan      html  css  js  c++  java
  • 洛谷P1514 引水入城

    P1514 引水入城

    题目描述

    在一个遥远的国度,一侧是风景秀美的湖泊,另一侧则是漫无边际的沙漠。该国的行政区划十分特殊,刚好构成一个N 行M 列的矩形,如上图所示,其中每个格子都代表一座城市,每座城市都有一个海拔高度。

    为了使居民们都尽可能饮用到清澈的湖水,现在要在某些城市建造水利设施。水利设施有两种,分别为蓄水厂和输水站。蓄水厂的功能是利用水泵将湖泊中的水抽取到所在城市的蓄水池中。

    因此,只有与湖泊毗邻的第1 行的城市可以建造蓄水厂。而输水站的功能则是通过输水管线利用高度落差,将湖水从高处向低处输送。故一座城市能建造输水站的前提,是存在比它海拔更高且拥有公共边的相邻城市,已经建有水利设施。由于第N 行的城市靠近沙漠,是该国的干旱区,所以要求其中的每座城市都建有水利设施。那么,这个要求能否满足呢?如果能,请计算最少建造几个蓄水厂;如果不能,求干旱区中不可能建有水利设施的城市数目。

    输入输出格式

    输入格式:

    输入文件的每行中两个数之间用一个空格隔开。输入的第一行是两个正整数N 和M,表示矩形的规模。接下来N 行,每行M 个正整数,依次代表每座城市的海拔高度。

    输出格式:

    输出有两行。如果能满足要求,输出的第一行是整数1,第二行是一个整数,代表最少建造几个蓄水厂;如果不能满足要求,输出的第一行是整数0,第二行是一个整数,代表有几座干旱区中的城市不可能建有水利设施。

    输入输出样例

    输入样例#1:
    【输入样例1】
    2 5
    9 1 5 4 3
    8 7 6 1 2
    
    【输入样例2】
    3 6
    8 4 5 6 4 4
    7 3 4 3 3 3
    3 2 2 1 1 2
    输出样例#1:
    【输出样例1】
    1
    1
    
    【输出样例2】
    1
    3

    说明

    【样例1 说明】

    只需要在海拔为9 的那座城市中建造蓄水厂,即可满足要求。

    【样例2 说明】

    上图中,在3 个粗线框出的城市中建造蓄水厂,可以满足要求。以这3 个蓄水厂为源头

    在干旱区中建造的输水站分别用3 种颜色标出。当然,建造方法可能不唯一。

    【数据范围】

    #include<iostream>
    #include<cstdio>
    #include<cstring>
    #define maxn 501
    using namespace std;
    int n,m,map[maxn][maxn],l,r,f[maxn];
    int mx[maxn],mn[maxn];
    int e[4][2]={{0,1},{0,-1},{-1,0},{1,0}};
    bool vis[maxn][maxn],v[maxn];
    void dfs(int x,int y,int num){
        if(x==n){
            v[y]=1;
            mx[num]=max(mx[num],y);
            mn[num]=min(mn[num],y);
        }
        for(int i=0;i<4;i++){
            int xx=x+e[i][0],yy=y+e[i][1];
            if(!vis[xx][yy]&&xx<=n&&xx>=1&&yy<=m&&yy>=1&&map[xx][yy]<map[x][y]){
                vis[xx][yy]=1;
                dfs(xx,yy,num);
            }
        }
    }
    int main(){
        scanf("%d%d",&n,&m);
        memset(mn,127,sizeof(mn));
        for(int i=1;i<=n;i++)for(int j=1;j<=m;j++)scanf("%d",&map[i][j]);
        for(int i=1;i<=m;i++){
            memset(vis,0,sizeof(vis));
            vis[1][i]=1;
            dfs(1,i,i);
        }
        int count=0;
        for(int i=1;i<=m;i++)count+=v[i];
        if(count<m){
            printf("0
    %d",m-count);
            return 0;
        }
        memset(f,0x3f,sizeof(f));
        f[0]=0;
        for(int i=1;i<=m;i++){
            for(int j=1;j<=m;j++){
                if(i<=mx[j]&&i>=mn[j]){
                    f[i]=min(f[i],f[mn[j]-1]+1);
                }
            }
        }
        printf("1
    %d",f[m]);
    }
    90分 第五个点T
    /*
        dfs前面加了一句if(map[1][i-1]<=map[1][i]&&map[1][i]>=map[1][i+1])
    */
    #include<iostream>
    #include<cstdio>
    #include<cstring>
    #define maxn 501
    using namespace std;
    int n,m,map[maxn][maxn],l,r,f[maxn];
    int e[4][2]={{1,0},{-1,0},{0,1},{0,-1}};
    bool vis[maxn][maxn],v[maxn];
    struct node{
        int mn,mx;
    }ra[maxn];
    int qread(){
        int i=0,j=1;
        char ch=getchar();
        while(ch<'0'||ch>'9'){if(ch=='-')j=-1;ch=getchar();}
        while(ch<='9'&&ch>='0'){i=i*10+ch-'0';ch=getchar();}
        return i*j;
    }
    void dfs(int x,int y,int num){
        if(x==n){
            v[y]=1;
            ra[num].mx=max(ra[num].mx,y);
            ra[num].mn=min(ra[num].mn,y);
        }
        for(int i=0;i<4;i++){
            int xx=x+e[i][0],yy=y+e[i][1];
            if(!vis[xx][yy]&&xx<=n&&xx>=1&&yy<=m&&yy>=1&&map[xx][yy]<map[x][y]){
                vis[xx][yy]=1;
                dfs(xx,yy,num);
            }
        }
    }
    int main(){
        n=qread();m=qread();
        for(int i=1;i<=m;i++)ra[i].mn=0x7fffffff;
        for(int i=1;i<=n;i++)for(int j=1;j<=m;j++)map[i][j]=qread();
        for(int i=1;i<=m;i++){
            if(map[1][i-1]<=map[1][i]&&map[1][i]>=map[1][i+1])
            memset(vis,0,sizeof(vis));
            vis[1][i]=1;
            dfs(1,i,i);
        }
        int count=0;
        for(int i=1;i<=m;i++)count+=v[i];
        if(count<m){
            printf("0
    %d",m-count);
            return 0;
        }
        for(int i=1;i<=m;i++)f[i]=0x7fffffff;
        f[0]=0;
        for(int i=1;i<=m;i++)
            for(int j=1;j<=m;j++)
                if(i<=ra[j].mx&&i>=ra[j].mn)
                    f[i]=min(f[i],f[ra[j].mn-1]+1);
        printf("1
    %d",f[m]);
    }
    100分
  • 相关阅读:
    经常遇到分析器错误信息: 访问被拒绝 "XXX组件名"
    文本格式检查,读取服务器端文本和客户端文本
    使用bcp,循环将本地txt文本导入远程sqlserver中
    Nginx高并发配置思路(轻松应对1万并发量)
    编译busybox时报错
    centos6.0桌面配置
    我的电脑每次点开的时候窗口都是最大化的怎么办?
    TQ2440上移植linux2.6.25时启动linux中free init 120kB 后卡住
    菜鸟编译Linux内核
    Linux/centos下查看硬件型号
  • 原文地址:https://www.cnblogs.com/thmyl/p/7656647.html
Copyright © 2011-2022 走看看