zoukankan      html  css  js  c++  java
  • 洛谷 P1902 刺杀大使

    刺杀大使

    一道并不难的二分题,竟让我交了上20次,诶,果然还是我太弱了。

    看完题目就基本想到要怎么做了:

    只需要对最小伤害代价进行二分即可,check()函数里用搜索判断是否可以到达最后一行,这里的check()用深搜广搜都可以,两种的代码下面都会给出,而经过检验,这道题目用深搜会优于广搜。

    如果你不像我一般手滑的话,此题基本就可以过了。

    然而,导致我反复提交20遍的原因,不是二分答案时卡循环的问题,而是,,,

    数组开小了

    这也给我提了个醒,不是所有的re都是二分循环的锅,有时候要考虑数组越界的问题。

    用汝佳julao的话说,就是 : 编写一个尽量鲁棒的程序!!!

    code:

    深搜做法(更优):

    #include <iostream>
    #include <cstdio>
    #include <cstring>
    using namespace std;
    //Mystery_Sky
    //
    #define M 2000
    #define INF 0x7f7f7f7f
    const int dx[] = {0, 0, 1, -1};
    const int dy[] = {1, -1, 0, 0};
    int l, r, mid;
    bool vis[M][M], flag;
    int n, m, a[M][M];
    void check(int x, int y, int ans)
    {
    	if(x == n)	{
    		flag = true;
    	}
    	for(int i = 0; i <= 3; i++) {
    		int xx = x + dx[i];
    		int yy = y + dy[i];
    		if(xx <= 0 || yy <= 0 || xx > n || yy > m || a[xx][yy] > ans || vis[xx][yy]) continue;
    		vis[xx][yy] = 1;
    		check(xx, yy, ans);
    		if(flag) return;
    	}
    
    }
    
    int main() {
    	scanf("%d%d", &n, &m);
    	for(int i = 1; i <= n; i++)
    		for(int j = 1; j <= m; j++)
    			scanf("%d", &a[i][j]), r = max(r, a[i][j]);
    	l = 0;
    	while(l <= r) {
    		mid = (l+r)/2;
    		memset(vis, 0, sizeof(vis));
    		flag = 0;
    		check(1, 1, mid);
    		if(flag) r = mid - 1;
    		else l = mid + 1;
    	}
    	printf("%d
    ", l);
    	return 0;
    }
    

    广搜做法:

    #include <iostream>
    #include <cstdio>
    #include <cstring>
    #include <queue>
    using namespace std;
    //Mystery_Sky
    //
    #define M 2000
    #define INF 0x7f7f7f7f
    struct node{
        int x, y;
    };
    int n, m, p[M][M];
    int l, r, mid, maxx;
    int vis[M][M];
    int dx[] = {0, 0, 1, -1};
    int dy[] = {1, -1, 0, 0};
    int Ans;
    inline bool check(int ans)
    {
        memset(vis, 0, sizeof(vis));
        queue <node> q;
        q.push((node){1, 1});
        while(!q.empty()) {
            node top = q.front();
            q.pop();
            int x, y;
            for(int i = 0; i <= 3; i++) {
                    x = top.x + dx[i];
                    y = top.y + dy[i];
                    if(x <= 0 || y <= 0 || x > n || y > m || p[x][y] > ans || vis[x][y]) continue;
                    vis[x][y] = 1;
                    q.push((node){x, y});
                    if(x == n)	return true; 
            }
        }
        return false;
    }
    
    int main() {
        scanf("%d%d", &n, &m);
        for(int i = 1; i <= n; i++)
            for(int j = 1; j <= m; j++) scanf("%d", &p[i][j]);
        l = 0, r = 1024;
        while(l < r) {
            mid = (l+r)>>1;
            if(check(mid)) {
                r = mid;
            }
            else l = mid+1;
        }
        printf("%d
    ", l);
        return 0;
    }
    
    唯愿,青春不辜负梦想,未来星辰闪耀
  • 相关阅读:
    win10下的MyEclipse2017 ci7 破解教程+全套资源+失败处理(转)
    layui layer.open() 弹层开启后 Enter回车 遮罩层无限弹处理
    layui 或者layer 父页面获取子页面数据 或者子页面获取父页面操作方法(转)
    layui弹出层两个以上置顶弹出
    div自动获焦并将光标定位到最后
    hibernate 的SessionFactory的getCurrentSession 与 openSession() 的区别
    形参与实参的区别
    linux下安装Mysql(干货!!!)解决mysql 1130问题,远程登录问题
    linux下安装Mysql(干货!!!)
    java文件上传与下载
  • 原文地址:https://www.cnblogs.com/Benjamin-cpp/p/10889917.html
Copyright © 2011-2022 走看看