【ACM省赛】第四届河南省程序设计大赛 D 走迷宫

题目链接:http://nyoj.top/web/contest/problem/cid/8/num/D

题目:

从左上走到右下,要求路径上的最大值与最小值的差值最小,输出最小值。

题解:

BFS+二分。

二分枚举插值,确定最小值,这样最大值也确定了。之后判断条件。

#include<bits/stdc++.h>
using namespace std;
typedef pair<int ,int> P; 
const int maxn=105;
int a[maxn][maxn];
int vis[maxn][maxn];
int nx[4]={0,0,1,-1};
int ny[4]={1,-1,0,0};
int MAX,MIN,n;
int bfs()
{
	queue<P> q;
	q.push(P(1,1));
	while(!q.empty())
	{
		P p=q.front();
		q.pop();
		if(vis[p.first][p.second]==1||(a[p.first][p.second]>MAX||a[p.first][p.second]<MIN))	continue;
		vis[p.first][p.second]=1;
		if(p.first==n&&p.second==n)	return 1;
		for(int i=0;i<4;i++)
		{
			int xx=nx[i]+p.first;
			int yy=ny[i]+p.second;
			if(a[xx][yy]<=MAX&&a[xx][yy]>=MIN&&vis[xx][yy]==0&&xx <= n && xx >= 1 && yy <= n && yy >= 1)
			{
				q.push(P(xx,yy));
			}
		}
	}
	return 0;
}
int f(int mid)
{
	for(int i=0;i+mid<=120;i++)
	{
		memset(vis,0,sizeof(vis));
		MIN=i;
		MAX=i+mid;
		if(bfs()) 	return 1;
	}
	return 0;
}
int main()
{
	while(cin>>n)
	{
		for(int i=1;i<=n;i++)
		for(int j=1;j<=n;j++)
			scanf("%d",&a[i][j]); 
		int l=0,r=120;
		while(l<r)
		{
			int mid=(l+r)/2;
			if(f(mid))
				r=mid;
			else 
				l=mid+1;
		}
		cout<<l<<endl;
	}
	return 0;
}
发布了119 篇原创文章 · 获赞 20 · 访问量 6万+

猜你喜欢

转载自blog.csdn.net/qq_40727946/article/details/89811637
今日推荐