洛谷 P1514 引水入城
这次不说闲话了,直接怼题
这道题用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 引水入城的更多相关文章
- 洛谷P1514 引水入城
洛谷P1514 引水入城 原题链接 一道好题...细节真多 第一次提交90分,然后就GG了,不知从何改起 其实比较简单吧... 首先,一个点的水流向最后一排,一定可以形成一个区间. 不行的话肯定GG ...
- 洛谷 P1514 引水入城 解题报告
P1514 引水入城 题目描述 在一个遥远的国度,一侧是风景秀美的湖泊,另一侧则是漫无边际的沙漠.该国的行政区划十分特殊,刚好构成一个 NN 行 \times M×M 列的矩形,如上图所示,其中每个格 ...
- CODEVS 1066/洛谷 P1514引水入城
1066 引水入城 2010年NOIP全国联赛提高组 时间限制: 1 s 空间限制: 128000 KB 题目等级 : 钻石 Diamond 题目描述 Description 在一个遥远的国 ...
- 洛谷P1514 引水入城 [搜索,区间DP]
题目传送门 引水入城 题目描述 在一个遥远的国度,一侧是风景秀美的湖泊,另一侧则是漫无边际的沙漠.该国的行政区划十分特殊,刚好构成一个 N 行×M 列的矩形,如上图所示,其中每个格子都代表一座城市,每 ...
- 洛谷P1514 引水入城——dfs
题目:https://www.luogu.org/problemnew/show/P1514 搜索+DP: 自己想出来的方法第一次80分好高兴! 再改了改就A了,狂喜乱舞: 也就是 dfs,仔细一想第 ...
- [NOIP2010] 提高组 洛谷P1514 引水入城
题目描述 在一个遥远的国度,一侧是风景秀美的湖泊,另一侧则是漫无边际的沙漠.该国的行政区划十分特殊,刚好构成一个N 行M 列的矩形,如上图所示,其中每个格子都代表一座城市,每座城市都有一个海拔高度. ...
- 洛谷P1514引水入城
题目 搜索加贪心其实并不需要用到\(DP\),搜索也是比较简单地搜索. 对于每个第一行的城市进行类似于滑雪那道题的搜索,然后记录最后一行它所覆盖的区间,易得一个一行城市只会有一个区间.然后可以在最后进 ...
- [luogu]P1514 引水入城[搜索][记忆化][DP]
[luogu]P1514 引水入城 引水入城 题目描述在一个遥远的国度,一侧是风景秀美的湖泊,另一侧则是漫无边际的沙漠.该国的行政区划十分特殊,刚好构成一个N 行M 列的矩形 ,如下图所示,其中每个格 ...
- Luogu P1514 引水入城
我承认我有点懒(洛谷已经发过题解了,但我发誓要坚持写博客) 这道题坑了我3天…… 首先一看就与染色问题类似,果断BFS(写DFS炸了) 先将最上面(靠近水)的一行全部扔进队列里,做一遍BFS 再对最下 ...
随机推荐
- 451. Sort Characters By Frequency (sort map)
Given a string, sort it in decreasing order based on the frequency of characters. Example 1: Input: ...
- cobian backup 11 使用
主机和备份机器创建备份用户(bf) 在备份机器上 设置备份用户, 备份目录右键安全,添加刚刚创建的备份bf用户,并授予所有权限 设置文件夹共享,并设置共享用户为刚刚创建的bf用户 并且在高级共享设置去 ...
- Flask (七) 部署
阿里云部署Flask项目 部署Flask项目和部署Django项目基本一致,我们也使用uwsgi+nginx 我们在部署Django项目基础上部署Flask项目 1, 将uwsgi.ini ...
- tensorflow:实战Google深度学习框架第四章02神经网络优化(学习率,避免过拟合,滑动平均模型)
1.学习率的设置既不能太小,又不能太大,解决方法:使用指数衰减法 例如: 假设我们要最小化函数 y=x2y=x2, 选择初始点 x0=5x0=5 1. 学习率为1的时候,x在5和-5之间震荡. im ...
- 535 Encode and Decode TinyURL 编码和解码精简URL地址
详见:https://leetcode.com/problems/encode-and-decode-tinyurl/description/ C++: class Solution { public ...
- 一些API
/** * Goto the specified frame index, and pause at this index. * @param startIndex The animation wil ...
- Partition(线段树的离线处理)
有一点类似区间K值的求法. 这里有两颗树,一个是自己建的线段树,一个是题目中给定的树.以线段树和树进行区分. 首先离散化一下,以离散化后的结果建线段树,线段树的节点开了2维,一维保存当前以当前节点为权 ...
- JavaScript实现的9大排序算法
笔试面试经常涉及各种算法,本文简要介绍常用的一些算法,并用JavaScript实现. 1.插入排序 1)算法简介 插入排序(Insertion-Sort)的算法描述是一种简单直观的排序算法.它的工作原 ...
- 访问者模式和php实现
访问者模式: 表示作用于某个对象结构中的各个元素的操作.它使你可以在不改变各个元素类的前提下定义作用于这些元素的操作. 角色: 1)抽象访问者:为该对象结构中具体元素角色声明一个访问操作接口.该操作接 ...
- C# 语句 分支语句
语句是指程序命令,按照顺序执行.可以分为 顺序语句 分支语句 循环语句 之前学习的内容都是按照顺序程序执行的,称之为顺序语句. 今天学的的内容是分支语句. 语句可以嵌套,可以是以分号结尾的单行 ...