这次不说闲话了,直接怼题


这道题用bfs其实并不难想,但比较困难的是怎么解决满足要求时输出蓄水厂的数量。其实就像其他题解说的那样,我们可以用bfs将它转化成一个区间覆盖问题,然后再进行贪心。

首先枚举每个靠近湖泊的城市,假设它建有蓄水站,然后从它开始广搜,搜到最后一行,也就靠近沙漠的城市后,记录能建输水站的一个区间。可能有人会问:如果一个蓄水站搜到的最后一行的区间不止一截,可能有多截怎么办呢? 我们可以这么思考:如果它有多截,那么每截中间肯定夹着一个(或一片)海拔比较高的城市,而且这个(片)城市的四面八方的海拔都比它小,那么这就是无解的,那一个(片)城市是无法建造输水站的。

我们在搜到最后一行时,记录下能被搜到的城市,在全部搜完后,我们再扫一遍记录的数组,如果都能被搜到,我们就用贪心去找最少的蓄水站,如果有城市是干旱区,那就很好处理了,输出无解+没被扫到的城市数量

代码:

#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
inline int read()  //快读
{
    short int k=0,f=1;
    char c=getchar();
    for(;!isdigit(c);c=getchar())
      if(c=='-')  f=-1;
    for(;isdigit(c);c=getchar())
      k=k*10+c-48;
    return k*f;
}
int vis[501][501]; int mapp[501][501]; //记录地图+寻找区间
struct zzz{
    int x,
        y;
}q[500*500+10];  int h=1,t; //搜索队列

struct hhh{
    int f,
        t;
}xd[1001];  int tot;  //记录区间

bool cmp(hhh x,hhh y)  //sort自定义比较函数
{
    if(x.f!=y.f)  return x.f<y.f;
    else  return x.t>y.t;
}

// 存四个方向
int fx[5]={0,1,0,-1,0};
int fy[5]={0,0,1,0,-1};

bool rqy[1001];  //存最后一行的城市是否被搜到过(听说用神犇的名字做变量会RP++)
int n,m;
int main()
{
    //======输入
    cin>>n>>m;
    for(int i=1;i<=n;i++)
      for(int j=1;j<=m;j++)
        cin>>mapp[i][j];
    //======搜索
    for(int i=1;i<=m;i++)
    {
        if(vis[1][i]) //这里用了一个剪枝:如果靠近湖泊的城市海拔较高,那么从这建一个蓄水站,旁边靠近湖泊的城市就不用再建蓄水站了,直接建输水站就行了,也就是说只要搜那海拔高的一个,就相当于把他周围的海拔低的能建蓄水站的城市全搜过了
          continue;
        memset(vis,0,sizeof(vis));
        h=1; t=0;
        q[++t].x=1, q[t].y=i; vis[1][i]=i;
        if(n==1)  //特别处理一下n=1时的测试点
          rqy[i]=1;
        while(h<=t)  //搜索主体
        {
            for(int j=1;j<=4;j++)
            {
                int xx=q[h].x+fx[j],yy=q[h].y+fy[j];
                if(xx<=0||yy<=0||xx>n||yy>m)
                  continue;
                if(!vis[xx][yy]&&mapp[q[h].x][q[h].y]>mapp[xx][yy])
                {
                    q[++t].x=xx;
                    q[t].y=yy;
                    vis[xx][yy]=i;
                    if(xx==n)
                      rqy[yy]=1;
                }
            }
            h++;
        }
        //===记录区间
        bool www=0;
        for(int j=1;j<=m+1;j++)
        {

            if(vis[n][j]&&!www)
            {
                xd[++tot].f=j;
                www=1;
            }
            if(www&&!vis[n][j])
            {
                xd[tot].t=j;
                break;
            }
        }
    }
    //======看每个城市能否被搜到
    int jjj=0;
    for(int i=1;i<=m;i++)
      if(rqy[i])
        jjj++;
    //如果不能全搜到
    if(jjj!=m)
    {
        cout<<0<<endl<<m-jjj;
        return 0;
    }

    //可以全搜到,贪心线段覆盖
    sort(xd+1,xd+tot+1,cmp);
    int now=0,to=0,ans=0;
    for(int i=1;i<=tot-1;i++)
    {
        if(now>=xd[i].f)
          to=max(xd[i].t,to);
        else
        {
            ans++;
            now=to;
            to=max(to,xd[i].t);
        }
    }
    cout<<1<<endl<<ans;
    return 0;
}

洛谷 P1514 引水入城的更多相关文章

  1. 洛谷P1514 引水入城

    洛谷P1514 引水入城 原题链接 一道好题...细节真多 第一次提交90分,然后就GG了,不知从何改起 其实比较简单吧... 首先,一个点的水流向最后一排,一定可以形成一个区间. 不行的话肯定GG ...

  2. 洛谷 P1514 引水入城 解题报告

    P1514 引水入城 题目描述 在一个遥远的国度,一侧是风景秀美的湖泊,另一侧则是漫无边际的沙漠.该国的行政区划十分特殊,刚好构成一个 NN 行 \times M×M 列的矩形,如上图所示,其中每个格 ...

  3. CODEVS 1066/洛谷 P1514引水入城

    1066 引水入城 2010年NOIP全国联赛提高组  时间限制: 1 s  空间限制: 128000 KB  题目等级 : 钻石 Diamond   题目描述 Description 在一个遥远的国 ...

  4. 洛谷P1514 引水入城 [搜索,区间DP]

    题目传送门 引水入城 题目描述 在一个遥远的国度,一侧是风景秀美的湖泊,另一侧则是漫无边际的沙漠.该国的行政区划十分特殊,刚好构成一个 N 行×M 列的矩形,如上图所示,其中每个格子都代表一座城市,每 ...

  5. 洛谷P1514 引水入城——dfs

    题目:https://www.luogu.org/problemnew/show/P1514 搜索+DP: 自己想出来的方法第一次80分好高兴! 再改了改就A了,狂喜乱舞: 也就是 dfs,仔细一想第 ...

  6. [NOIP2010] 提高组 洛谷P1514 引水入城

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

  7. 洛谷P1514引水入城

    题目 搜索加贪心其实并不需要用到\(DP\),搜索也是比较简单地搜索. 对于每个第一行的城市进行类似于滑雪那道题的搜索,然后记录最后一行它所覆盖的区间,易得一个一行城市只会有一个区间.然后可以在最后进 ...

  8. [luogu]P1514 引水入城[搜索][记忆化][DP]

    [luogu]P1514 引水入城 引水入城 题目描述在一个遥远的国度,一侧是风景秀美的湖泊,另一侧则是漫无边际的沙漠.该国的行政区划十分特殊,刚好构成一个N 行M 列的矩形 ,如下图所示,其中每个格 ...

  9. Luogu P1514 引水入城

    我承认我有点懒(洛谷已经发过题解了,但我发誓要坚持写博客) 这道题坑了我3天…… 首先一看就与染色问题类似,果断BFS(写DFS炸了) 先将最上面(靠近水)的一行全部扔进队列里,做一遍BFS 再对最下 ...

随机推荐

  1. CodeForces599C【贪心】

    题意: 给你一个序列,要求你从小到大排序,你可以划分成一个块一个块地进行块内排序,问你最多能分成几个块 思路: 贪心,首先感觉就是有正序的话我就分开啊: 难道倒序不能分块?321肯定不行啊. 存不存在 ...

  2. 根运动 (Root Motion) – 工作原理

    http://blog.csdn.net/myarrow/article/details/45505085 1. 基本概念 在Unity3D动画中,模型的位置.角度经常会发生变化,我们需要决定是否将模 ...

  3. 自定义socket 模拟B/S服务端

    目录 通过什么实现连接? B/S 客户端与服务端交互过程 socket server端 python代码 (静态html反馈) socket server端 python代码 (动态html反馈) 小 ...

  4. Spring security + oauth2.0 + redis + mybatis plus 搭建微服务

    上个星期一个朋友请求帮忙,让我搭建一个分布式授权中心的微服务,之前我也没搭建过,在网上撸了几天前辈们写的技术博客,搞出个模型,分享给大家: 前辈们博客地址: OAuth2.0 原理:https://b ...

  5. Info.plist配置相关文件访问权限

    <key>NSAppleMusicUsageDescription</key> <string>App需要您的同意,才能访问媒体资料库</string> ...

  6. Technocup 2017 - Elimination Round 1 (Unofficially Open for Everyone, Rated for Div. 2) A

    Vasily has a number a, which he wants to turn into a number b. For this purpose, he can do two types ...

  7. 修正 FreeBSD 字体锯齿问题

    如果你给 FreeBSD 安装完图形界面,一登录就被满屏幕不论中英全是锯齿且残缺不堪入目的文字吓了一跳,那一定是安装了文泉驿字体.先不必急着卸载文泉驿,只需简单修改相关配置即可恢复正常显示.这是因为文 ...

  8. 解决 openSUSE 中 Sublime Text 3 的中文显示和输入问题

    测试环境 系统版本:openSUSE Leap 42.2 桌面环境:KDE Plasma 5输入法:fcitx-rime (中州韵) 见周围用 Windows 和 macOS 的小伙伴几乎都在用简单强 ...

  9. 关于JVM的一些东西

    1.在JDK1.6(HotSpot虚拟机)及之前,运行时常量池(属于方法区的一部分)是永久代的,而在JDK1.7之后运行时常量池(里面用于存放编译期生成的各种字面量和符号引用,这部分内容将在类加载后进 ...

  10. linux 设置固定IP centOS6.5

    主要是要把Linux的IP固定下来,可以用另一台机器SSH连接. ping的用法: 基本语法:ping [-选项] IP地址或域名 功能描述:测试网络是否连通 常用选项:-c -c 指定发送数据包的次 ...