NOIP 2010 引水入城

题目链接:

点我

题目分析

\(dfs\)+记忆化
首先\(dfs\)一下求下面的点是不是能全被覆盖到,打一个标记
顺便记忆化一下最后一排左右延伸能延伸到哪里
然后对于最后一排如果能流满,那么还有一个性质,每个起点能覆盖的最后一排是一个连续段
这一点证明可以看洛谷博客,简单来说就是如果两个起点的水流在某个点流到一起了,那顺着分叉一定能流到另外一边的
代码细节实现上还是不够熟练,裸的\(dfs\)写的很多了,但是带一点记忆化/剪枝的有时候就写不出来,还是要多做题

代码:

#include<bits/stdc++.h>
#define N (1000 + 10)
using namespace std;
inline int read() {
    int cnt = 0, f = 1; char c = getchar();
    while (!isdigit(c)) {if (c == '-') f = -f; c = getchar();}
    while (isdigit(c)) {cnt = (cnt << 3) + (cnt << 1) + (c ^ 48); c = getchar();}
    return cnt * f;
}
int n, m, Map[N][N], flow[N][N];
int l[N][N], r[N][N], cnt;
const int fx[4] = {-1, 0, 1, 0};
const int fy[4] = {0, 1, 0, -1};
void dfs_(int d, int x, int y){
    if (flow[x][y]) return;
    flow[x][y] = d;
    for (register int i = 0; i < 4; ++i) {
        int dx = x + fx[i], dy = y + fy[i];
        if (Map[dx][dy] >= Map[x][y]) continue;
        if (dx > n || dy > m) continue; 
        if (dx < 1 || dy < 1) continue;
        dfs_(d, dx, dy);
        l[x][y] = min(l[dx][dy], l[x][y]);
        r[x][y] = max(r[dx][dy], r[x][y]);
    }
}
int main() {
//  freopen("1.in", "r", stdin);
    n = read(), m = read();
    memset(l, 0x3f, sizeof l);
    for (register int i = 1; i <= n; ++i) 
        for (register int j = 1; j <= m; ++j) Map[i][j] = read();
    for (register int i = 1; i <= m; ++i) l[n][i] = r[n][i] = i;
    for (register int i = 1; i <= m; ++i) if (!flow[1][i]) dfs_(i, 1, i);
    int flag = 0;
    for (register int i = 1; i <= m; ++i) 
        if (!flow[n][i]) ++flag;
    if (flag) {
        puts("0");
        return printf("%d", flag), 0;
    }
    int L = 1;
    while (L <= m) {
        int R = 0;
        for (register int i = 1; i <= m; ++i) if (l[1][i] <= L) R = max(R, r[1][i]);
        ++cnt;
        L = R + 1;
    }
    puts("1"); printf("%d", cnt);
    return 0;
}
weixin063传染病防控宣传微信小程序系统的设计与实现+springboot后端毕业源码案例设计 1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 4、下载使用后,可先查看README.md或论文文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。 5、资源来自互联网采集,如有侵权,私聊博主删除。 6、可私信博主看论文后选择购买源代码。 1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 4、下载使用后,可先查看README.md或论文文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。 5、资源来自互联网采集,如有侵权,私聊博主删除。 6、可私信博主看论文后选择购买源代码。 1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 4、下载使用后,可先查看README.md或论文文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。 5、资源来自互联网采集,如有侵权,私聊博主删除。 6、可私信博主看论文后选择购买源代码。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值