nyoj306 走迷宫(搜索+二分)

走迷宫

时间限制: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
来源
第四届河南省程序设计大赛
上传者
张云聪

这种思路的确是没想到

由于这道题的难度范围是0-120  可以对难度二分的方法

因为我深搜超时了  百度找到的思路。

也就是找到一个确定的难度

#include <stdio.h>
#include <string.h>
int map[105][105];
bool vis[105][105];
int max,min,n;
bool ok;
int dir[4][2]={1,0,-1,0,0,1,0,-1};
bool limit(int x,int y)
{
	if(vis[x][y]||x<0||y<0||x==n||y==n||ok)
	return false;
	return true;
}
void dfs(int x,int y,int l,int r)
{
	if(x==n-1&&y==n-1)
	{
		ok=true;
		return ;
	}
	for(int i=0;i<4;i++)
	{
		int xx=x+dir[i][0];
		int yy=y+dir[i][1];
		if(limit(xx,yy)&&map[xx][yy]>=l&&map[xx][yy]<=r)
		{
			vis[xx][yy]=true;
			dfs(xx,yy,l,r);
		}
	}
}
bool find(int k)
{
	for(int i=min;i<=max;i++)
	{
		if(i+k>max)
		break;
		if(map[0][0]<i||map[0][0]>i+k) continue;
		if(map[n-1][n-1]<i||map[n-1][n-1]>i+k) continue;
		memset(vis,false,sizeof(vis));
		ok=false;
		dfs(0,0,i,i+k);
		if(ok)
		return true;
	}
	return false;
}
int bin_search()
{
	int l=0,r=max-min,mid;
	while(l<=r)
	{
		mid=(l+r)/2;
		if(find(mid))
		r=mid-1;
		else
		l=mid+1;
	}
	return l;
}
int main()
{
	while(~scanf("%d",&n))
	{
		max=-0x3fffffff;
		min=0x3fffffff;
		for(int i=0;i<n;i++)
		{
			for(int j=0;j<n;j++)
			{
				scanf("%d",&map[i][j]);
				max=map[i][j]>max?map[i][j]:max;
				min=map[i][j]<min?map[i][j]:min;
			}
		}
		printf("%d\n",bin_search());
	}
	return 0;
} 
时间: 2024-10-06 15:18:31

nyoj306 走迷宫(搜索+二分)的相关文章

NYOJ306 走迷宫(dfs+二分搜索)

题目描述 http://acm.nyist.net/JudgeOnline/problem.php?pid=306 Dr.Kong设计的机器人卡多非常爱玩,它常常偷偷跑出实验室,在某个游乐场玩之不疲.这天卡多又跑出来了,在SJTL游乐场玩个不停,坐完碰碰车,又玩滑滑梯,这时卡多又走入一个迷宫.整个迷宫是用一个N * N的方阵给出,方阵中单元格中填充了一个整数,表示走到这个位置的难度. 这个迷宫可以向上走,向下走,向右走,向左走,但是不能穿越对角线.走迷宫的取胜规则很有意思,看谁能更快地找到一条路

第四章 搜索(深度、广度搜索、全排列、走迷宫、再解炸弹人、宝岛探险、水管工游戏)

一.深度优先搜索DFS 深度优先搜索DFS的关键思想是:当下应该怎么做(每个方法都试一遍),这一步解决后,进入下一步,下一步的解决方法和这一步的解决方法是一样的 DFS的基本模型 void dfs(int step) { 判断边界 尝试每一种可能  for(i=1;i<=n;i++) { 继续下一步 dfs(step+1) } 返回 } 1.1全排列 1 //输入一个数n 2 //输出1-n的全排列 3 #include <stdio.h> 4 int n, book[10], a[10

ybt 1252 广度优先搜索 走迷宫(二维、最小步数)

1252:走迷宫 时间限制: 1000 ms         内存限制: 65536 KB提交数: 7272     通过数: 3241 [题目描述] 一个迷宫由R行C列格子组成,有的格子里有障碍物,不能走:有的格子是空地,可以走. 给定一个迷宫,求从左上角走到右下角最少需要走多少步(数据保证一定能走到).只能在水平方向或垂直方向走,不能斜着走. [输入] 第一行是两个整数,R和C,代表迷宫的长和宽.( 1≤ R,C ≤ 40) 接下来是R行,每行C个字符,代表整个迷宫. 空地格子用‘.’表示,

数据结构之深度优先搜索(走迷宫)

在此以走迷宫为例: 给定迷宫起点和终点,看能否到达:(xt,yt) void f(int x,int y){ if(x<0||x>21||y<0||y>21){//判断是否超出迷宫 return; } ch[x][y]='#'; for(i=0;i<4;i++){if(ch[x][y]=='.'){ if(x==xt+1&&y==yt+1){ flag=1; return ; } //四个方向 f(x,y+1); f(x,y-1); f(x+1,y); f(x

数据结构之 栈与队列--- 走迷宫(深度搜索dfs)

走迷宫 Time Limit: 1000MS Memory limit: 65536K 题目描述 一个由n * m 个格子组成的迷宫,起点是(1, 1), 终点是(n, m),每次可以向上下左右四个方向任意走一步,并且有些格子是不能走动,求从起点到终点经过每个格子至多一次的走法数. 输入 第一行一个整数T 表示有T 组测试数据.(T <= 110) 对于每组测试数据: 第一行两个整数n, m,表示迷宫有n * m 个格子.(1 <= n, m <= 6, (n, m) !=(1, 1)

深度优先算法——走迷宫的实现

深度优先搜索算法(Depth-First-Search),是搜索算法的一种.是沿着树的深度遍历树的节点,尽可能深的搜索树的分支.当节点v的所有边都己被探寻过,搜索将回溯到发现节点v的那条边的起始节点.这一过程一直进行到已发现从源节点可达的所有节点为止.如果还存在未被发现的节点,则选择其中一个作为源节点并重复以上过程,整个进程反复进行直到所有节点都被访问为止.属于盲目搜索. 深度优先搜索是图论中的经典算法,利用深度优先搜索算法可以产生目标图的相应拓扑排序表,利用拓扑排序表可以方便的解决很多相关的图

Python 之 使用Tkinter 做GUI 研究机器人走迷宫

这本是课程的一个作业研究搜索算法,当时研究了一下Tkinter,然后写了个很简单的机器人走迷宫的界面,并且使用了各种搜索算法来进行搜索,如下图: 使用A*寻找最优路径: 由于时间关系,不分析了,我自己贴代码吧.希望对一些也要用Tkinter的人有帮助. from Tkinter import * from random import * import time import numpy as np import util class Directions: NORTH = 'North' SOU

SDUT 2449 数据结构实验之栈与队列十:走迷宫

数据结构实验之栈与队列十:走迷宫 Time Limit: 1000 ms Memory Limit: 65536 KiB Problem Description 一个由n * m 个格子组成的迷宫,起点是(1, 1), 终点是(n, m),每次可以向上下左右四个方向任意走一步,并且有些格子是不能走动,求从起点到终点经过每个格子至多一次的走法数. Input 第一行一个整数T 表示有T 组测试数据.(T <= 110) 对于每组测试数据: 第一行两个整数n, m,表示迷宫有n * m 个格子.(1

青蛙走迷宫问题(体力值)

题目: 青蛙走迷宫,1代表路通,0代表不通:起点是(0, 0),终点是(0,m - 1);青蛙每次向上走需要消耗体力值为3,向下走不消耗体力值,平走消耗体力值1:根据给定值判断青蛙是否可以根据初始值到达终点,并求出消耗体力值最少的路径: 举例: n = 4, m =4, p = 10(体力值) 4 4 10 1 0 0 1 1 1 0 1 0 1 1 1 0 0 1 1 则结果为:[[0, 0], [1, 0], [1, 1], [2, 1], [2, 2], [2, 3], [1, 3], [