题目传送门

这道题开始看好像并没有什么思路,和搜索好像也并没有什么关系。但是我们手玩下样例就会发现,思路其实就三句话:(写这道题的时候在代码里写的)

  • //我们想知道从第1行的每列往下到干旱区的范围

  • //要求这个直接bfs就行了

  • //然后就转换为了一个最小线段覆盖了

写了个bfs,在学长的blog那里看了看线段覆盖怎么搞,于是就交了,开始是30分,因为bfs的时候我只用了3个方向。开始以为它是不能向上建水站的,后来想想其实也可以,只要满足有公共边+高度有落差就行了...再交就90分了\(qwq\),T了一个点,开了氧气优化+快读,然后A了(???)

// luogu-judger-enable-o2
#include<cstdio>
#include<algorithm>
#include<cstring>
#include<queue> using namespace std; int n,m,ans,tot;
int la[600][600],tong[600],fla[600];
bool vis[600][600];
int dx[5]={0,0,1,0,-1};
int dy[5]={0,-1,0,1,0};
struct segment{
int l,r;
}p[600]; void re(int &x)
{
x=0;
char ch=getchar();
bool flag=false;
while(ch<'0'||ch>'9') flag|=(ch=='-'),ch=getchar();
while(ch>='0'&&ch<='9') x=(x<<3)+(x<<1)+(ch^48),ch=getchar();
x=flag ? -x : x;
} bool valid(int x,int y)
{
if(x>=1&&x<=n&&y>=1&&y<=m) return 1;
return 0;
} bool cmp(segment x,segment y)
{
return x.l<y.l;
} void bfs(int x,int y)
{
memset(vis,0,sizeof(vis));
queue<pair<int,int> >q;
q.push(make_pair(x,y));
vis[x][y]=1;
while(!q.empty())
{
int nx=q.front().first;
int ny=q.front().second;
q.pop();
for(int i=1;i<=4;i++)
{
int xx=nx+dx[i];
int yy=ny+dy[i];
if(valid(xx,yy)&&la[nx][ny]>la[xx][yy]&&!vis[xx][yy])
q.push(make_pair(xx,yy)),vis[xx][yy]=1;
}
}
int l=99999,r=0;
for(int j=1;j<=m;j++)
if(vis[n][j]) tong[y]++,fla[j]++,l=min(l,j),r=max(r,j);
if(!tong[y]) return ;
p[++tot].l=l,p[tot].r=r;
} int main()
{
//我们想知道从第1行的每列往下到干旱区的范围
//要求这个直接bfs就行了
//然后就转换为了一个最小线段覆盖了
re(n);re(m);
for(int i=1;i<=n;i++)
for(int j=1;j<=m;j++)
re(la[i][j]);
for(int j=1;j<=m;j++)
bfs(1,j);
// for(int j=1;j<=m;j++) printf("%d %d\n",p[j].l,p[j].r);
for(int j=1;j<=m;j++)
if(!fla[j]) ans++;
if(ans) {printf("0\n%d",ans);return 0;}
sort(p+1,p+tot+1,cmp);
int s=1;
for (int i=1;i<=m;i++)
{
int r=0;
for (int j=1;j<=m;j++)
if (p[j].l<=s&&p[j].r>=s) r=max(r,p[j].r);
ans++;
s=r+1;
if (s>m) break;
}
printf("1\n%d",ans);
return 0;
}

为什么会T呢?刚才我们的算法复杂度其实严格是\(O(n^3+nlogn+n^2)\)的。开始不解为什么搜索会是\(O(n^3)\),想了想后发现这是网格图,遍历所有点一遍是\(O(n^2)\)的。而本题极限数据\(500\),可能会跑到一亿,超时。

刚才我们有最直观的想法:从第一行的每列出发向下搜索,但事实上我们可以不对所有第一行的位置进行向下搜索。只对那些满足\(h[1][i]>=h[1][i-1]\)而且\(h[1][i]>=h[1][i+1]\)的点进行搜索。因为当前点如果不满足这些条件,那么它形成的区间一定可以被其他区间覆盖,这个区间就没什么用了。

// luogu-judger-enable-o2
#include<cstdio>
#include<algorithm>
#include<cstring>
#include<queue> using namespace std; int n,m,ans,tot;
int la[600][600],tong[600],fla[600];
bool vis[600][600];
int dx[5]={0,0,1,0,-1};
int dy[5]={0,-1,0,1,0};
struct segment{
int l,r;
}p[600]; void re(int &x)
{
x=0;
char ch=getchar();
bool flag=false;
while(ch<'0'||ch>'9') flag|=(ch=='-'),ch=getchar();
while(ch>='0'&&ch<='9') x=(x<<3)+(x<<1)+(ch^48),ch=getchar();
x=flag ? -x : x;
} bool valid(int x,int y)
{
if(x>=1&&x<=n&&y>=1&&y<=m) return 1;
return 0;
} bool cmp(segment x,segment y)
{
return x.l<y.l;
} void bfs(int x,int y)
{
memset(vis,0,sizeof(vis));
queue<pair<int,int> >q;
q.push(make_pair(x,y));
vis[x][y]=1;
while(!q.empty())
{
int nx=q.front().first;
int ny=q.front().second;
q.pop();
for(int i=1;i<=4;i++)
{
int xx=nx+dx[i];
int yy=ny+dy[i];
if(valid(xx,yy)&&la[nx][ny]>la[xx][yy]&&!vis[xx][yy])
q.push(make_pair(xx,yy)),vis[xx][yy]=1;
}
}
int l=99999,r=0;
for(int j=1;j<=m;j++)
if(vis[n][j]) tong[y]++,fla[j]++,l=min(l,j),r=max(r,j);
if(!tong[y]) return ;
p[++tot].l=l,p[tot].r=r;
} int main()
{
//我们想知道从第1行的每列往下到干旱区的范围
//要求这个直接bfs就行了
//然后就转换为了一个最小线段覆盖了
re(n);re(m);
for(int i=1;i<=n;i++)
for(int j=1;j<=m;j++)
re(la[i][j]);
for(int j=1;j<=m;j++)
if(la[1][j]>=la[1][j-1]&&la[1][j]>=la[1][j+1])
bfs(1,j);
// for(int j=1;j<=m;j++) printf("%d %d\n",p[j].l,p[j].r);
for(int j=1;j<=m;j++)
if(!fla[j]) ans++;
if(ans) {printf("0\n%d",ans);return 0;}
sort(p+1,p+tot+1,cmp);
int s=1;
for (int i=1;i<=m;i++)
{
int r=0;
for (int j=1;j<=m;j++)
if (p[j].l<=s&&p[j].r>=s) r=max(r,p[j].r);
ans++;
s=r+1;
if (s>m) break;
}
printf("1\n%d",ans);
return 0;
}

Luogu P1514引水入城【搜索】 By cellur925的更多相关文章

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

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

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

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

  3. 【luogu P1514 引水入城】 题解

    题目链接:https://www.luogu.org/problemnew/show/P1514 // luogu-judger-enable-o2 #include <iostream> ...

  4. Luogu P1514 引水入城

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

  5. [NOIp2010] luogu P1514 引水入城

    跟 zzy, hwx 等人纠结是否回去上蛋疼的董老板的课. 题目描述 如图所示.你有一个 N×MN\times MN×M 的矩阵,水可以从一格流到与它相邻的格子,需要满足起点的海拔严格高于终点海拔.定 ...

  6. LUOGU P1514 引水入城 (bfs)

    传送门 解题思路 拉了很长的战线,换了好几种写法终于过了..首先每个蓄水场一定是对沙漠造成连续一段的贡献,所以可以$bfs$出每种状态,然后做一次最小区间覆盖,但这样的复杂度有点高.就每次只搜那些比左 ...

  7. Luogu 1514 引水入城 (搜索,动态规划)

    Luogu 1514 引水入城 (搜索,动态规划) Description 在一个遥远的国度,一侧是风景秀美的湖泊,另一侧则是漫无边际的沙漠.该国的行政区划十分特殊,刚好构成一个N行M列的矩形,如上图 ...

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

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

  9. 洛谷P1514 引水入城

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

随机推荐

  1. parameters arguments 形式参数 实际参数

    parameter和argument的区别 – 笑遍世界 http://smilejay.com/2011/11/parameter_argument/ https://en.wikipedia.or ...

  2. java replaceAll Replace

    java ReplaceAll 的两个参数都必须是正则表达式. 在正则表达式中 \ (一个斜线)是用 \\ 来表示(即:用两个斜线表示一个斜线) 而在Java语言中 \ (一个斜线)是用 \\ 来表示 ...

  3. Lua学习笔记(1) ——语法

    1.  Lua -i main.lua -i 进入交互模式 -l 加载一个库 -e  “lua code” 直接在命令行执行lua code 2. 注释 -- This is a line comme ...

  4. 向HTML页面传入参数

    这次是想将参数传入HTML页面,通过js获取参数信息,动态生成HTML页面内容: 方法一: <script> function GetArgsFromHref(sHref, sArgNam ...

  5. LightOJ1245 Harmonic Number (II) —— 规律

    题目链接:https://vjudge.net/problem/LightOJ-1245 1245 - Harmonic Number (II)    PDF (English) Statistics ...

  6. 将PHP数组输出为HTML表格

    1. [代码][PHP]代码    <?phpclass xtable{    private $tit,$arr,$fons,$sextra;    public function __con ...

  7. PHP Json函数不能处理中文的解决办法

    PHP5.2 新增的 json 功能是非常受欢迎的,但是经过测试发现,json_encode 对中文的处理是有问题的: 不能处理GB编码,所有的GB编码都会替换成空字符: utf8编码的中文被编码成u ...

  8. 使用idea导入远程git版本库项目

    1.选择git方式导入 2.设置远程git项目地址 3.测试是否连接成功 4.选择yes,检查项目 5.如果有下一步,直接next下去就可以了.

  9. 机器学习:Principal components analysis (主分量分析)

    Principal components analysis 这一讲,我们简单介绍Principal Components Analysis(PCA),这个方法可以用来确定特征空间的子空间,用一种更加紧 ...

  10. 使用 @RequestMapping 映射请求