洛谷P1514 [NOIP2010提高组T4]引水入城
P1514 引水入城
题目描述
在一个遥远的国度,一侧是风景秀美的湖泊,另一侧则是漫无边际的沙漠。该国的行政区划十分特殊,刚好构成一个N 行M 列的矩形,如上图所示,其中每个格子都代表一座城市,每座城市都有一个海拔高度。
为了使居民们都尽可能饮用到清澈的湖水,现在要在某些城市建造水利设施。水利设施有两种,分别为蓄水厂和输水站。蓄水厂的功能是利用水泵将湖泊中的水抽取到所在城市的蓄水池中。
因此,只有与湖泊毗邻的第1 行的城市可以建造蓄水厂。而输水站的功能则是通过输水管线利用高度落差,将湖水从高处向低处输送。故一座城市能建造输水站的前提,是存在比它海拔更高且拥 有公共边的相邻城市,已经建有水利设施。由于第N 行的城市靠近沙漠,是该国的干旱区,所以要求其中的每座城市都建有水利设施。那么,这个要求能否满足呢?如果能,请计算最少建造几个蓄水厂;如果不能,求 干旱区中不可能建有水利设施的城市数目。
输入输出格式
输入格式:
输入文件的每行中两个数之间用一个空格隔开。输入的第一行是两个正整数N 和M,表示矩形的规模。接下来N 行,每行M 个正整数,依次代表每座城市的海拔高度。
输出格式:
输出有两行。如果能满足要求,输出的第一行是整数1,第二行是一个整数,代表最少建造几个蓄水厂;如果不能满足要求,输出的第一行是整数0,第二行是一个整数,代表有几座干旱区中的城市不可能建有水利设施。
输入输出样例
- 【输入样例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
- 【输出样例2】
- 1
- 3
说明
【样例1 说明】
只需要在海拔为9 的那座城市中建造蓄水厂,即可满足要求。
【样例2 说明】
上图中,在3 个粗线框出的城市中建造蓄水厂,可以满足要求。以这3 个蓄水厂为源头
在干旱区中建造的输水站分别用3 种颜色标出。当然,建造方法可能不唯一。
【数据范围】
【题解】
第一次bfs判断可行性
第二次bfs得到每个点能灌溉到的底部区间
可以证明有解当且仅当每个点覆盖到的区间时连续的
然后变成了区间覆盖的贪心
按左端点排序,每次选右端点最远的那一个
hwzer的贪心骚操作秒啊!
易错:
为了在dfs中对l,r进行处理,把l赋值为INF,导致
贪心时出错,应及时退出
- #include <iostream>
- #include <cstdio>
- #include <cstdlib>
- #include <cstring>
- #include <algorithm>
- #include <queue>
- #define min(a, b) ((a) < (b) ? (a) : (b))
- #define max(a, b) ((a) > (b) ? (a) : (b))
- inline void swap(int &x, int &y)
- {
- long long tmp = x;x = y;y = tmp;
- }
- inline void read(int &x)
- {
- x = ;char ch = getchar(), c = ch;
- while(ch < '' || ch > '')c = ch, ch = getchar();
- while(ch <= '' && ch >= '')x = x * + ch - '', ch = getchar();
- if(c == '-')x = -x;
- }
- const int INF = 0x3f3f3f3f;
- const int MAXN = + ;
- const int dx[] = {,,-,};
- const int dy[] = {,,,-};
- struct Node
- {
- int l, r;
- Node(int _l, int _r){l = _l;r = _r;}
- Node(){l = INF;r = ;}
- }node[MAXN][MAXN];
- int n,m,g[MAXN][MAXN],b[MAXN][MAXN],ans;
- //可行性判断
- void dfs1(int x, int y)
- {
- b[x][y] = ;
- for(register int i = ;i < ;++i)
- {
- int xx = x + dx[i], yy = y + dy[i];
- if(xx <= || yy <= || xx > n || yy > m || b[xx][yy] || g[xx][yy] >= g[x][y])continue;
- dfs1(xx, yy);
- }
- }
- void dfs(int x, int y)
- {
- b[x][y] = ;
- if(x == n)node[x][y].l = min(node[x][y].l, y), node[x][y].r = max(node[x][y].r, y);
- for(register int i = ;i < ;++ i)
- {
- int xx = x + dx[i], yy = y + dy[i];
- if(xx <= || yy <= || xx > n || yy > m || g[xx][yy] >= g[x][y])continue;
- if(b[xx][yy])
- {
- node[x][y].l = min(node[x][y].l, min(node[xx][yy].l, yy));
- node[x][y].r = max(node[x][y].r, max(node[xx][yy].r, yy));
- continue;
- }
- dfs(xx, yy);
- node[x][y].l = min(node[x][y].l, min(node[xx][yy].l, yy));
- node[x][y].r = max(node[x][y].r, max(node[xx][yy].r, yy));
- }
- }
- int cmp(Node a, Node b)
- {
- return a.l == b.l ? a.r < b.r : a.l < b.l;
- }
- int main()
- {
- read(n), read(m);
- for(register int i = ;i <= n;++ i)
- for(register int j = ;j <= m;++ j)
- read(g[i][j]);
- for(register int i = ;i <= m;++ i)
- if(!b[][i])dfs1(,i);
- for(register int i = ;i <= m;++ i)
- if(!b[n][i])
- ++ ans;
- if(ans)
- {
- printf("0\n%d", ans);
- return ;
- }
- memset(b, , sizeof(b));
- for(register int i = ;i <= m;++ i)
- if(!b[][i])
- dfs(, i);
- std::sort(node[] + , node[] + + m, cmp);
- int far = , now = ;
- for(register int i = ;i <= m && now < m;++ i)
- if(node[][i].l <= now + )far = max(far,node[][i].r);
- else now = far, far = max(far, node[][i].r), ++ans;
- if(now != m)++ ans;
- printf("1\n%d", ans);
- return ;
- }
洛谷P1514
洛谷P1514 [NOIP2010提高组T4]引水入城的更多相关文章
- 洛谷-机器翻译-NOIP2010提高组复赛
题目背景 小晨的电脑上安装了一个机器翻译软件,他经常用这个软件来翻译英语文章. 题目描述 这个翻译软件的原理很简单,它只是从头到尾,依次将每个英文单词用对应的中文含义来替换.对于每个英文单词,软件会先 ...
- 洛谷 1541 NOIp2010提高组 乌龟棋
[题解] 很容易想到这是一个DP,f[i][j][k][l]表示4种卡片分别用了多少张,那么转移方程就是f[i][j][k][l]=Max(f[i-1][j][k][l],f[i][j-1][k][l ...
- 洛谷 P2678 & [NOIP2015提高组] 跳石头
题目链接 https://www.luogu.org/problemnew/show/P2678 题目背景 一年一度的“跳石头”比赛又要开始了! 题目描述 这项比赛将在一条笔直的河道中进行,河道中分布 ...
- 洛谷 P1025 & [NOIP2001提高组] 数的划分(搜索剪枝)
题目链接 https://www.luogu.org/problemnew/show/P1025 解题思路 一道简单的dfs题,但是需要剪枝,否则会TLE. 我们用dfs(a,u,num)来表示上一个 ...
- 洛谷P1084 [NOIP2012提高组Day2T3]疫情控制
P1084 疫情控制 题目描述 H 国有 n 个城市,这 n 个城市用 n-1 条双向道路相互连通构成一棵树,1 号城市是首都,也是树中的根节点. H 国的首都爆发了一种危害性极高的传染病.当局为了控 ...
- 洛谷P1083 [NOIP2012提高组Day2T2]借教室
P1083 借教室 题目描述 在大学期间,经常需要租借教室.大到院系举办活动,小到学习小组自习讨论,都需要向学校申请借教室.教室的大小功能不同,借教室人的身份不同,借教室的手续也不一样. 面对海量租借 ...
- 洛谷P1315 [NOIP2011提高组Day2T3] 观光公交
P1315 观光公交 题目描述 风景迷人的小城Y 市,拥有n 个美丽的景点.由于慕名而来的游客越来越多,Y 市特意安排了一辆观光公交车,为游客提供更便捷的交通服务.观光公交车在第 0 分钟出现在 1号 ...
- 洛谷P1313 [NOIP2011提高组Day2T1]计算系数
P1313 计算系数 题目描述 给定一个多项式(by+ax)^k,请求出多项式展开后x^n*y^m 项的系数. 输入输出格式 输入格式: 输入文件名为factor.in. 共一行,包含5 个整数,分别 ...
- 洛谷P1312 [NOIP2011提高组Day1T3]Mayan游戏
Mayan游戏 题目描述 Mayan puzzle是最近流行起来的一个游戏.游戏界面是一个 7 行5 列的棋盘,上面堆放着一些方块,方块不能悬空堆放,即方块必须放在最下面一行,或者放在其他方块之上.游 ...
随机推荐
- 用React实现一个自动生成文章目录的组件
原文地址:小寒的博客 功能介绍 这个组件的效果呐,就是你在浏览这个页面的时候点击右上角的叉叉看到的那个文章目录. 功能很简单,就是根据文章内容自动生成这个目录,可以快速跳转. 需要的知识点 正则 do ...
- 深入浅出 Java Concurrency (25): 并发容器 part 10 双向并发阻塞队列 BlockingDeque[转]
这个小节介绍Queue的最后一个工具,也是最强大的一个工具.从名称上就可以看到此工具的特点:双向并发阻塞队列.所谓双向是指可以从队列的头和尾同时操作,并发只是线程安全的实现,阻塞允许在入队出队不满足条 ...
- Spring框架使用ByName自动注入同名问题剖析
问题描述 我们在使用spring框架进行项目开发的时候,为了配置Bean的方便经常会使用到Spring当中的Autosire机制,Autowire根据注入规则的不同又可以分为==ByName==和 ...
- sql语句怎么看效率?
1.数据库设计当面: 对查询进行优化,应该尽量避免全表扫描,首先应考虑在where及order by设计的列上加索引. d.索引并不是越多越好,索引可以提高查询效率,同时降低了insert和updat ...
- [转]浅谈C#中常见的委托
一提到委托,浮现在我们脑海中的大概是听的最多的就是类似C++的函数指针吧,呵呵,至少我的第一个反应是这样的. 关于委托的定义和使用,已经有诸多的人讲解过,并且讲解细致入微,尤其是张子阳的那一篇.我就不 ...
- 【codeforces 505C】Mr.Kitayuta,the Treasure Hunter
[题目链接]:http://codeforces.com/problemset/problem/505/C [题意] 一开始你跳一步长度为d; 之后你每步能跳d-1,d,d+1这3种步数; 然后在路上 ...
- 双系统可以进入Windows但进入Ubuntu时无法进入系统引导,只有左上角光标闪
双系统可以进入Windows但进入Ubuntu时无法进入系统引导,只有左上角光标闪 这时候可以进入windows下的easyBCD重新创建ubuntu引导项即可
- 2018.10.29安装tensorflow
先安装tensorflow时按照中文社区安装,结果安装的0.5版本与cuda和cudnn版本不一样,后面才知道需要安好对应版本安装. 1.卸载protobuf pip uninstall protob ...
- (转)AngularJS中使用的表单验证
原文 http://www.cnblogs.com/woshinidezhu/p/Form-validation-with-AngularJS.html 客户端表单验证是AngularJS里面最酷的 ...
- TP5隐藏index.php
一,找到/public/.htaccess文件,如果你的入口文件已经移动到根目录下,那么你的.htaccess文件也要剪切到根目录下,总之要确保.htaccess跟入口的index.php保持同级. ...