poj 2110 Mountain Walking 枚举+bfs

题意:

给一个n*n的矩阵,要从左上角走到右下角,使经过数字的最大数与最小数的差最小。

分析:

一开始想到了二分这个差,然后判断是否存在路径,每次只知道差的话深搜每次搜索要记录沿途的最大值和最小值会tle,广搜的话如果节点只记录x,y坐标,搜索中存在要重新访问以前访问过节点的情况,比如一开始(1,1)->(1,2)->(2,2),如果(2,1)这个点的值更合适,最优访问路径(1,1)->(2,1)->(2,2),也就是(2,2)要被重新访问,不满足广搜每个节点只访问一次的原则,只有增加节点维度每个节点记录x,y坐标和到达它经过的最小最大值,显然不好。后来了解到可以加大枚举,不仅枚举差,还枚举路径上的最大值,这样每次路径上的最大最小值就确定了,可以广搜。

//poj 2110
//sep9
#include <iostream>
#include <queue>
using namespace std;
const int maxN=128;
struct Node
{
	int x,y;
};

int g[maxN][maxN];
int vis[maxN][maxN];
int dirx[4]={0,0,-1,1};
int diry[4]={-1,1,0,0};
int n,diff,min_hight,max_hight;
queue<Node> q;

bool pass(int low,int high)
{
	memset(vis,0,sizeof(vis));
	Node a;
	a.x=1,a.y=1;
	if(g[1][1]>high||g[1][1]<low)
		return false;
	while(!q.empty()) q.pop();
	q.push(a);
	vis[1][1]=1;
	while(!q.empty()){
		Node t=q.front();q.pop();
		int x=t.x,y=t.y;
		for(int k=0;k<4;++k){
			int nx=x+dirx[k];
			int ny=y+diry[k];
			if(nx>=1&&nx<=n&&ny>=1&&ny<=n&&vis[nx][ny]==0&&g[nx][ny]<=high&&g[nx][ny]>=low){
				Node a;
				a.x=nx,a.y=ny;
				q.push(a);
				vis[nx][ny]=1;
				if(nx==n&&ny==n) return true;
			}
		}
	}
	return false;
}

bool work(int mid)
{
	for(int high=min_hight;high<=max_hight;++high){
		int low=high-mid;
		if(pass(low,high))
			return true;
	}
	return false;

}

int main()
{
	scanf("%d",&n);
	min_hight=INT_MAX;
	max_hight=INT_MIN;
	for(int i=1;i<=n;++i)
		for(int j=1;j<=n;++j){
			scanf("%d",&g[i][j]);
			min_hight=min(min_hight,g[i][j]);
			max_hight=max(max_hight,g[i][j]);
		}
	int ans,l=0,r=max_hight+1,mid;
	while(l<r){
		mid=(l+r)/2;
		if(work(mid)){
			r=mid;
			ans=mid;
		}else
			l=mid+1;
	}
	printf("%d",ans);
	return 0;
} 
时间: 2024-10-07 00:27:35

poj 2110 Mountain Walking 枚举+bfs的相关文章

POJ 2110 Mountain Walking 二分+bfs

传送门 昨天看到这个题还以为是个脑残的dp, 然而脑残的是我. 题目意思就是从左上角走到右下角, 设x为路径上的最大值-最小值, 求x的最小值. 二分x, 对于每一个x, 枚举下界lower, lower从0开始枚举, 每一次bfs的时候, 如果一个点的值小于lower或者大于lower+x, 那么就不走这个点, 看最后能否走到终点. 自己的整数二分写的真是不忍直视...改了好久. 1 #include<bits/stdc++.h> 2 using namespace std; 3 #defi

POJ 2110 Mountain Walking 暴力搜索+二分

题意:n*n的矩阵 每次能走四个方向,定义路径的花费为:路径中方格的max-min,问从左上到右下的最小花费,n<=100 4个方向不是DAG,不能DP,暴力搜索 每个点最坏情况下走n*n 共n*n个点 O(n^4)TLE二分ans后 枚举下界,则此时知道路径的最小值和最大值从 起点出发把mn<=c<=mx的点都遍历,此时dfs 相当于遍历图,不用回溯,复杂度为O(n^3*logn) #include <iostream> #include <cstring> #

[ACM] POJ 1753 Flip Game (枚举,BFS,位运算)

Flip Game Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 29921   Accepted: 12975 Description Flip game is played on a rectangular 4x4 field with two-sided pieces placed on each of its 16 squares. One side of each piece is white and the

POJ 2251 Dungeon Master --- 三维BFS(用BFS求最短路)

POJ 2251 题目大意: 给出一三维空间的地牢,要求求出由字符'S'到字符'E'的最短路径,移动方向可以是上,下,左,右,前,后,六个方向,每移动一次就耗费一分钟,要求输出最快的走出时间.不同L层的地图,相同RC坐标处是相连通的.(.可走,#为墙) 解题思路:从起点开始分别往6个方向进行BFS(即入队),并记录步数,直至队为空.若一直找不到,则困住. /* POJ 2251 Dungeon Master --- 三维BFS(用BFS求最短路) */ #include <cstdio> #i

POJ 1101 The Game(BFS+判方向)

    The Game Description One morning, you wake up and think: "I am such a good programmer. Why not make some money?'' So you decide to write a computer game. The game takes place on a rectangular board consisting of w * h squares. Each square might o

poj 3087 Shuffle&#39;m Up (bfs)

Description A common pastime for poker players at a poker table is to shuffle stacks of chips. Shuffling chips is performed by starting with two stacks of poker chips, S1 and S2, each stack containing C chips. Each stack may contain chips of several

POJ 2251:Dungeon Master(三维BFS)

Dungeon Master Time Limit: 1000MS Memory Limit: 65536K Total Submissions: 16178 Accepted: 6268 Description You are trapped in a 3D dungeon and need to find the quickest way out! The dungeon is composed of unit cubes which may or may not be filled wit

HDU 4771 Stealing Harry Potter&#39;s Precious (生成排列+枚举 + BFS)

Stealing Harry Potter's Precious Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) Total Submission(s): 1982    Accepted Submission(s): 931 Problem Description Harry Potter has some precious. For example, his invisib

poj 1465 &amp; zoj 1136 Multiple (BFS+余数重判)

Multiple Time Limit: 1000MS   Memory Limit: 32768K Total Submissions: 6177   Accepted: 1346 Description a program that, given a natural number N between 0 and 4999 (inclusively), and M distinct decimal digits X1,X2..XM (at least one), finds the small