HDU 1072 NYOJ 483 Nightmare -- BFS+允许回头

/*
	有两种做法:
	一个不考虑走了回头路,因为数据是在是小,几乎不浪费时间
	另一个是用贪心策略,先假设所有点剩余时间为0,只要该点剩余时间小于 上一点剩余时间-1 
	则修改remain值为remain-1再入队,否则不入队
*/


#include <iostream>
#include <cstring>
#include <cstdio>
#include <queue>
#include <algorithm>
using namespace std;
#define CLR(c,v) (memset(c,v,sizeof(c)))


const int M         = 30;
const int wall      = 0;
const int road      = 1;
const int start     = 2;
const int end       = 3;
const int reset     = 4;
const int bomblimit = 6;
int revise[][2]     = {{-1,0},
			       {0,-1},{0,1},
			          {1,0}};


int map[M][M];
int limit[M][M];
int n,m; // n*m

struct _P{
	int x,y;
	int step,remain;
	_P(int x=-1,int y=-1,int step=0,int remain=0):x(x),y(y),step(step),remain(remain){}
	bool operator <(const _P& p){
		return step > p.step;
	}
	bool operator ==(const _P& p){
		return (x==p.x) && (y==p.y);
	}
}S,E;
typedef _P NEXT;
typedef _P NOW;


int BFS(){
	queue<_P> que;
	que.push(S);
	while(!que.empty()){
		NOW now = que.front();
		que.pop();
		if (now == E){
			return now.step;
		}
		for (int i = 0 ; i < 4 ; i++){
			int nx = now.x + revise[i][0];
			int ny = now.y + revise[i][1];
			int re = now.remain - 1;
			if ( !(nx >= 0 && nx < n && ny >= 0 && ny < m ) || re <= 0)continue; // 出界 或 时间耗尽
			if (map[nx][ny] == wall)continue;

			NEXT next = NEXT( nx, ny, now.step+1, re );
			if (map[nx][ny] == reset){
				next.remain = bomblimit;
			}
			if (limit[nx][ny] < next.remain){ // 只有当剩余时间发现-1之后 还长的 才入队
				limit[nx][ny] = next.remain;
				que.push(next);
			}
		}
	}
	return -1;
}


int main(){
	//freopen("in.txt","r",stdin);
	//freopen("Input.txt","r",stdin);
	//freopen("out.txt","w",stdout);
	int Ncase,g;
	cin >> Ncase;
	while(Ncase -- ){
		cin >> n >> m;
		CLR(limit,0);
		for (int i = 0 ; i <n ; i ++){
			for  (int j = 0 ; j < m ; j++){
				scanf("%d",&g);
				map[i][j] = g;
				//limit[i][j] = 0; // 初始化
				if (g == start){
					S = _P(i,j,0,bomblimit);
					limit[i][j] = bomblimit;
				}else if(g == end){
					E = _P(i,j,0,0);
					map[i][j] = road;
				}
			}
		}
		cout << BFS() << endl;
	}

	return 0;
}



/*
 一些变态的数据,不符合input
13
8 8
2 1 1 1 1 1 1 1
1 1 1 1 1 1 1 1
1 4 1 1 1 1 1 1
1 1 1 1 1 1 1 1
1 1 1 1 1 1 1 1
1 1 1 4 1 1 4 1
1 1 1 1 1 1 1 1
1 1 1 1 1 1 1 3
4 4
2 1 1 1
1 1 1 1
1 1 4 1
1 1 1 3
20 20
4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4
4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4
4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4
4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4
4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4
4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4
4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4
4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4
4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4
4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4
4 4 4 4 4 4 4 4 4 2 4 4 4 4 4 4 4 4 4 4
4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4
4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4
4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4
4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4
4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4
4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4
4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4
4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4
4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 3

5 8
1 2 1 1 1 1 1 4 
1 0 0 0 1 0 0 1 
1 4 1 0 1 1 0 1 
1 0 0 0 0 3 0 1 
1 1 4 1 1 1 1 1 

2 8
2 1 1 1 1 1 1 0
0 0 1 4 1 1 1 3

8 8
2 4 4 4 4 4 4 4
4 4 4 4 4 4 4 4
4 4 4 4 4 4 4 4
4 4 4 4 4 4 4 4
4 4 4 4 4 4 4 4
4 4 4 4 4 4 4 4
4 4 4 4 4 4 4 4
4 4 4 4 4 4 4 3


2 1
2 
3


3 3
2 1 1
1 1 0
1 1 3

4 8
2 1 1 0 1 1 1 0
1 0 4 1 1 0 4 1
1 0 0 0 0 0 0 1
1 1 1 4 1 1 1 3

1 2
2 3

3 3
2 4 1
1 4 1
1 4 3

1 8
2 4 4 4 4 4 4 3

1 8
2 0 0 0 0 0 0 3

8 8
2 1 0 0 0 0 0 0
1 4 1 0 0 0 0 0
0 1 4 1 0 0 0 0
0 0 1 4 1 0 0 0
0 0 0 1 4 1 0 0
0 0 0 0 1 4 1 0
0 0 0 0 0 1 4 1
0 0 0 0 0 0 1 3

8 8
2 1 4 4 0 0 0 0
1 0 1 0 0 0 0 0
0 1 4 1 0 4 0 0
4 0 1 0 1 0 0 0
0 0 1 1 4 1 1 4
0 0 4 0 1 0 1 0
0 0 0 0 0 1 1 1
0 0 0 0 4 0 1 3



*/

你可能感兴趣的:(C++)