走迷宫

时间限制:1000 ms  |  内存限制:65535 KB
难度:5
 
描述
Dr.Kong设计的机器人卡多非常爱玩,它常常偷偷跑出实验室,在某个游乐场玩之不疲。这天卡多又跑出来了,在SJTL游乐场玩个不停,坐完碰碰车,又玩滑滑梯,这时卡多又走入一个迷宫。整个迷宫是用一个N * N的方阵给出,方阵中单元格中填充了一个整数,表示走到这个位置的难度。

这个迷宫可以向上走,向下走,向右走,向左走,但是不能穿越对角线。走迷宫的取胜规则很有意思,看谁能更快地找到一条路径,其路径上单元格最大难度值与最小难度值之差是最小的。当然了,或许这样的路径不是最短路径。

机器人卡多现在在迷宫的左上角(第一行,第一列)而出口在迷宫的右下角(第N行,第N列)。

卡多很聪明,很快就找到了这样的一条路径。你能找到吗?

 
输入
有多组测试数据,以EOF为输入结束的标志
第一行: N 表示迷宫是N*N方阵 (2≤ N≤ 100)
接下来有N行, 每一行包含N个整数,用来表示每个单元格中难度 (0≤任意难度≤120)。
输出
输出为一个整数,表示路径上最高难度与和最低难度的差。
样例输入
5
1 1 3 6 8
1 2 2 5 5
4 4 0 3 3
8 0 2 3 4
4 3 0 2 1
样例输出
2
来源
第四届河南省程序设计大赛
上传者
张云聪
上下左右四个方向,走的方式太多了简直无法暴力搜索。难度差最大为120,考虑从这里下手,
找出迷宫中的最大值与最小值,这两个数的差值就是最大的难度差,最小的难度差为零,然后二分在这个区间里枚举难度差直到找到最优解。
切记不要多此一举的回溯,这样会导致TLE(并不是每个搜索都需要回溯)。
找到mid=(l+r)/2,然后把难度差控制在[l,mid]直接搜索,若有解则将r的值更新为mid,否则将l的值更新为mid+1,每次都会缩小一半的范围;
对于给定的一个mid,找到所有符合条件的区间逐个枚举,发现路径后及时退出。

#include<iostream>
#include<cstdio>
#include<cstring>
using namespace std;
int n,ok,e[105][105];
int minn=999999999,maxn=-1;
bool vis[105][105];
int fx[4][2]={-1,0,1,0,0,1,0,-1};
int read()
{
int s=0;
char ch=getchar();
while(ch<'0'||ch>'9') ch=getchar();
while(ch>='0'&&ch<='9') {s=s*10+ch-'0';ch=getchar();}
return s;
}
void dfs(int x,int y,int l,int r)
{
if(ok) return;
if(x==n&&y==n) {ok=1;return;}
for(int i=0;i<4;++i){if(ok) return;
int dx=x+fx[i][0];
int dy=y+fx[i][1];
if(dx>=1&&dy>=1&&dx<=n&&dy<=n&&e[dx][dy]>=l&&e[dx][dy]<=r&&!vis[dx][dy]){
vis[dx][dy]=1;
dfs(dx,dy,l,r);
//vis[dx][dy]=0;
}
}
}
bool Find(int k)
{
for(int i=minn;i+k<=maxn;++i){

if(e[1][1]<i||e[1][1]>i+k) continue;//当前地图值不在查找范围内
if(e[n][n]<i||e[n][n]>i+k) continue;
ok=0;
memset(vis,0,sizeof(vis));
vis[1][1]=1;
dfs(1,1,i,i+k);
if(ok) return true;
}
return false;
}
int solve()
{
int l=0,r=maxn-minn,mid;
while(l<r){
mid=(l+r)/2; //cout<<mid<<endl;
if(Find(mid)) r=mid;
else l=mid+1;
}
return l;
}
int main()
{
int i,j;
while(cin>>n){minn=999999999;maxn=-1;
for(i=1;i<=n;++i)
for(j=1;j<=n;++j) {e[i][j]=read();
if(e[i][j]<minn) minn=e[i][j];
if(e[i][j]>maxn) maxn=e[i][j];
}//cout<<minn<<" "<<maxn<<endl;
printf("%d\n",solve());
}
return 0;
}

nyoj306 二分+DFS的更多相关文章

  1. Codeforces Round #381 (Div. 2)D. Alyona and a tree(树+二分+dfs)

    D. Alyona and a tree Problem Description: Alyona has a tree with n vertices. The root of the tree is ...

  2. [BZOJ 1082] [SCOI2005] 栅栏 【二分 + DFS验证(有效剪枝)】

    题目链接:BZOJ - 1082 题目分析 二分 + DFS验证. 二分到一个 mid ,验证能否选 mid 个根木棍,显然要选最小的 mid 根. 使用 DFS 验证,因为贪心地想一下,要尽量先用提 ...

  3. 51nod1307(暴力树剖/二分&dfs/并查集)

    题目链接: http://www.51nod.com/onlineJudge/questionCode.html#!problemId=1307 题意: 中文题诶~ 思路: 解法1:暴力树剖 用一个数 ...

  4. 【BZOJ】1082: [SCOI2005]栅栏(二分+dfs)

    http://www.lydsy.com/JudgeOnline/problem.php?id=1082 题意:n个给出木板,m个给出木板.可以将那m个木板锯成泥想要的长度.问最大能锯成多少个给出的n ...

  5. 【BZOJ】1146: [CTSC2008]网络管理Network(树链剖分+线段树套平衡树+二分 / dfs序+树状数组+主席树)

    http://www.lydsy.com/JudgeOnline/problem.php?id=1146 第一种做法(时间太感人): 第二种做法(rank5,好开心) ================ ...

  6. (hdu)5652 India and China Origins 二分+dfs

    题目链接:http://acm.split.hdu.edu.cn/showproblem.php?pid=5652 Problem Description A long time ago there ...

  7. 第四届河南省省赛 走迷宫 二分+DFS

    题目思路:使用二分查找路径中最大值和最小值之间的差值,从而确定出一组minn和maxn,对此组的minn和maxn经行DFS,如果可以找到一条路径,其中的最大值,最小值在minn~maxn的范围内,则 ...

  8. [SCOI2005]栅栏 二分+dfs

    这个题真的是太nb了,各种骚 二分答案,肯定要减最小的mid个,从大往小搜每一个木板,从大往小枚举所用的木材 当当前木材比最短的木板还短,就扔到垃圾堆里,并记录waste,当 waste+sum> ...

  9. BZOJ 1082 栅栏(二分+DFS剪枝)

    首先,长度短的木板一定比长度长的木板容易得到,因此若要得到最多的木板,它们必定是所有木板中最短的——可以对木板排序后二分答案(用k表示). 判断是否合法就用搜索,但数据有点大,要用到两个剪枝.一个是若 ...

随机推荐

  1. 设置(更改)Mysql 自增ID的起始值

    SELECT * FROM segwords WHERE id>790511 DELETE FROM segwords WHERE id>790511 #下面这句是设置的 ALTER TA ...

  2. Qt中layout()->setSizeConstraint(QLayout::SetFixedSize);崩溃的问题

    编译环境: win764位,vs2008编译器,cbd调试器,qt4.8 背景: 按照<C++ Gui Qt4编程>书中第二章的一个例子(sortDialog)一步步抄完,编译运行,显示不 ...

  3. iOS之第三方库以及XCode插件介绍

    前言 第三方库是现在的程序员离不开的东西 不光是APP开发 基本上所有的商业项目 都会或多或少的使用到第三方库 Github上Star>100的开源库数量如下 可以看到JS以绝对的优势排名第一 ...

  4. 2018 Java线程热门面试题,你知道多少?

    面试,难还是不难?取决于面试者的底蕴(气场+技能).心态和认知及沟通技巧.面试其实可以理解为一场聊天和谈判,在这过程中有心理.思想上的碰撞和博弈.其实你只需要搞清楚一个逻辑:“面试官为什么会这样问?他 ...

  5. 怎样将一个整数转化成字符串数,并且不用函数itoa

    #include<iostream> using namespace std; int main() { , j = , i = ; ], str[]; while (num) { tem ...

  6. 手撕vue-cli配置——webpack.dev.conf.js篇

    const utils = require('./utils') const webpack = require('webpack') const config = require('../confi ...

  7. ssh连接linux服务器不断开- "Write failed: Broken pipe"

    我自己用阿里云的服务器的时候,发现ssh连上以后,一会不用就断掉了,非常不方便,服务端的系统是ubuntu. 查了些东西,原来可以去配置服务端的sshd,或者客户端的ssh,就行了. 1,配置服务器端 ...

  8. centos 安装 ffmpeg

    使用yum方式安装ffmpeg: 先安装Nux Dextop仓库: Nux Dextop库依赖于EPEL库,所有要先安装EPEL库(需要管理员权限). 如果安装过则跳过. $ su root $ yu ...

  9. C# 获取枚举的描述属性

    在使用枚举类型时,我们需要取名称和值,甚至有时候还需要取枚举类型的描述.通过反射,我们能获取到枚举类型的描述属性. 首先我们需要给枚举类型添加描述属性(属性都没有是不可能取到的),[Descripti ...

  10. JavaScript 获取地址栏参数

    1. function a() { console.log(this); } a.call(null); window 如果第一个参数传入的对象调用者是null或者undefined的话,call方法 ...