第四届河南省acm省赛 走迷宫(二分法枚举差值和最大值最小值+DFS)

走迷宫

时间限制: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
来源

第四届河南省程序设计大赛

#include <iostream>

#include<cstdio>

#include<cstring>

using namespace std;

int map[105][105],fang[4][2]={{1,0},{-1,0},{0,1},{0,-1}},biao[105][105];

int m;

int min1,max1;

int DFS(int x,int y)

{

int i,dx,dy,q;

if(map[x][y]>max1||map[x][y]<min1)

return 0;

if(x==m-1&&y==m-1)

return 1;

for(i=0;i<4;i++)

{

dx=x+fang[i][0];

dy=y+fang[i][1];

if(dx>=0&&dy>=0&&dx<m&&dy<m&&biao[dx][dy]==0)

{

biao[dx][dy]=1;

q=DFS(dx,dy);

//biao[dx][dy]=0;//这里不用回溯,因为他只是要求到达m-1,m-1点。

if(q==1)

return 1;

}

}

return 0;

}

int ju(int cha)

{

int i,j,q;

for(i=0;i+cha<120;i++)//枚举最大值最小值。

{

memset(biao,0,sizeof(biao));

min1=i;

max1=i+cha;

biao[0][0]=1;

q=DFS(0,0);

biao[0][0]=0;

if(q==1)

return 1;

}

return 0;

}

int main()

{

while(~scanf("%d",&m))

{

int i,j;

for(i=0;i<m;i++)

{

for(j=0;j<m;j++)

{

scanf("%d",&map[i][j]);

}

}

int l=0,r=120,mid,min3;

while(l<r)//二分法枚举差值。

{

mid=(l+r)/2;

if(ju(mid)==1)

{//printf("a%d %d %d\n",l,r,mid);

min3=mid;

r=mid;

}

else

{

l=mid+1;

}

}

printf("%d\n",l);

}

return 0;

}

时间: 2024-10-28 11:10:51

第四届河南省acm省赛 走迷宫(二分法枚举差值和最大值最小值+DFS)的相关文章

第四届河南省acm省赛 BOBSLEDDING

BOBSLEDDING 时间限制:1000 ms  |  内存限制:65535 KB 难度:3 描述 Dr.Kong has entered a bobsled competition because he hopes his hefty weight will give his an advantage over the L meter course (2 <= L<= 1000). Dr.Kong will push off the starting line at 1 meter per

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

题目: 青蛙走迷宫,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], [

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

题目思路:使用二分查找路径中最大值和最小值之间的差值,从而确定出一组minn和maxn,对此组的minn和maxn经行DFS,如果可以找到一条路径,其中的最大值,最小值在minn~maxn的范围内,则查找成功.继续向左查找,否则向右查找 #include<iostream> #include<algorithm> #include<cstring> #include<vector> #include<stdio.h> #include<qu

[河南省ACM省赛-第四届] 表达式求值(nyoj 305)

栈的模拟应用: #include<iostream> #include<cstdio> #include<cstring> #include<string> #include<cstdlib> #include<algorithm> #include<stack> using namespace std; string getPostfixExp(string s) { stack<char> sta;// d

[河南省ACM省赛-第四届] 序号互换 (nyoj 303)

相似与27进制的转换 #include<iostream> #include<cstdio> #include<cstring> #include<string> #include<cstdlib> #include<algorithm> #include<stack> using namespace std; int main(){ int t; string s; cin>>t; while(t--) {

[河南省ACM省赛-第四届] Substring (nyoj 308)

练习使用字符串函数了. 1.字串的反转也是它的字串,2.最长,3.最先出现 string: #include<iostream> #include<cstdio> #include<cstring> #include<string> #include<algorithm> using namespace std; int main() { int t, n; string s; cin>>t; while(t--){ cin>&

[河南省ACM省赛-第三届] 网络的可靠性 (nyoj 170)

题目链接:http://acm.nyist.net/JudgeOnline/problem.php?pid=170 根据题意,需要找到度数为1的结点个数,如下图: #include<iostream> #include<cstdio> #include<cstring> #include<vector> using namespace std; #define N 10002 vector<int> g[N]; int main() { freo

[河南省ACM省赛-第五届] 最强DE 战斗力 (nyoj 541)

题解链接:http://acm.nyist.net/JudgeOnline/problem.php?pid=541 几天前百度题解后用数学知识AC的,后来大牛说这是一道动态规划题. 网上的数学解题链接:http://blog.csdn.net/x314542916/article/details/8204583 d(i) = max{d(j)*d(n-j) | 1<= j <=n/2}; 用Java写比较简单 import java.math.BigInteger; import java.u

[河南省ACM省赛-第三届] 房间安排 (nyoj 168)

题目链接:http://acm.nyist.net/JudgeOnline/problem.php?pid=168 分析:找到一天中需要最多的房间即可 #include<iostream> #include<cstdio> #include<algorithm> #include<cstring> using namespace std; #define N 200 int day[N];//day[i] 第i天的最多房间数 int main() { fre