hdoj 1180 BFS,优先队列
规范的BFS写法,可以很有效地避免一些状态判重和状态转移上的细节错误,以下总结了三点。
//hdoj 1180
#include <iostream>
#include <cstdio>
#include <queue>
using  namespace std;
struct Node {
	int x, y, step;
};
bool operator< ( Node n1, Node n2 ) {
	return n1.step > n2.step;
}
int n, m;
int dir[4][2] = { 0, 1, 1, 0, 0, -1, -1, 0 };
char mp[25][25];
bool mark[25][25];
Node _s;
void input() {
	int i, j;
	for( i=0; i<n; ++i ) scanf( "%s", mp[i] );
	for( i=0; i<n; ++i ) {
		for( j=0; j<n; ++j ) {
			if( mp[i][j] == 'S' ) {
				_s.x = i;
				_s.y = j;
				_s.step = 0;
			}
		}
	}
}
inline bool isBond( Node nd ) {
	if( nd.x < 0 || nd.y < 0 || nd.x >= n || nd.y >= m || mp[nd.x][nd.y] == '*' ) return 1;
	return 0;
}
int solve() {
	priority_queue<Node> Q;
	Node p, q;
	int i;
	Q.push( _s );
	memset(mark, 0, sizeof(mark) );
	mark[_s.x][_s.y] = 1;
	while( !Q.empty() ) {
		p = Q.top();
		Q.pop();
		if( mp[p.x][p.y] == 'T' ) return p.step; //1.放这里判断比放for里面保险,虽然多花了点时间。
		for( i=0; i<4; ++i ) {
			q.x = p.x + dir[i][0];
			q.y = p.y + dir[i][1];
			q.step = p.step + 1;                 //2.走完后步数马上加
			if( isBond( q ) || mark[q.x][q.y] ) continue;
			if( mp[q.x][q.y] == '.' || mp[q.x][q.y] == 'T' ) {
				Q.push( q );
				mark[q.x][q.y] = 1;              //3.每次push后,马上跟新mark
				continue;
			} else if( mp[q.x][q.y] == '|' ) {
				if( p.step % 2 == 1 && i % 2 == 1 ) q.step ++;
				if( p.step % 2 == 0 && i % 2 == 0 ) q.step ++;
			} else if( mp[q.x][q.y] == '-' ) {
				if( p.step % 2 == 1 && i % 2 == 0 ) q.step ++;
				if( p.step % 2 == 0 && i % 2 == 1 ) q.step ++;
			}
			q.x += dir[i][0];
			q.y += dir[i][1];
			if( isBond(q) || mark[q.x][q.y] ) continue;
			Q.push( q );
			mark[q.x][q.y] = 1;
		}
	}
	return -1;
}
int main() {
//	freopen( "c:/aaa.txt", "r", stdin );
	while( scanf("%d %d", &n, &m) == 2 ) {
		input();
		printf( "%d\n", solve() );
	}
	return 0;
}
                    
                
                
            
        
浙公网安备 33010602011771号