hdoj 1175 http://acm.hdu.edu.cn/showproblem.php?pid=1175
这题是简单的搜索,给图图中的两个位置,问这两个位置是否可以消去。
有以下情况不能消去:
1,起点和终点有任意一个是非法点,即不是图中的点;
2,起点和终点有任意一个是数值为0的点,即该点事空的。
3,起点和终点的数值不相同。
4,起点和终点的最短距离大于2,这个最短距离是指转弯的次数。
前3点都是直接可以处理的,对于第四点我是采用bfs搜的。记录当前节点的方向和转弯次数即可。
在hdoj c++ 提交 跑了109ms, 弱啊 !
View Code
1 // 用node记录上一次的方向,但是结束条件不是找到终点就返回结果,这样会出错// 2 #include <iostream> 3 #include <cstdio> 4 #include <queue> 5 #include <cstring> 6 #include <algorithm> 7 using namespace std; 8 9 #define maxn 1088 10 int n, m; 11 int g[maxn][maxn]; 12 int step[4][2]={{0,-1}, {0,1},{1,0},{-1,0} }; 13 14 void init(){ 15 for ( int i=1; i<=n; ++i ) 16 for ( int j=1; j<=m; ++j ) 17 scanf ("%d", &g[i][j]); 18 } 19 20 struct Node{ 21 int x, y; 22 Node(){} 23 Node(int X, int Y):x(X), y(Y){} 24 void scan(){ 25 scanf("%d%d", &x, &y); 26 } 27 }s, e; 28 29 int dist[maxn][maxn]; 30 31 // 判断两个节点是否相等 32 bool is(Node a, Node b){ 33 return ( a.x==b.x && a.y==b.y); 34 } 35 // 判断点是否合法 36 bool ok(int x, int y){ 37 if(x<1 || y<1 || x>n || y>m) return 0; 38 return 1; 39 } 40 41 bool bfs(Node a, Node b) { 42 if(!ok(a.x, a.y) || !ok(b.x, b.y)) return 0; 43 if(g[a.x][a.y] != g[b.x][b.y]) return 0; 44 if(!g[a.x][a.y] || !g[b.x][b.y]) return 0; 45 if(is(a, b) ) return 0; 46 47 for ( int i=1; i<=n; ++i ) 48 for ( int j=1; j<=m; ++j ) 49 dist[i][j] = 30000; 50 51 queue<Node > Q; 52 while(!Q.empty() ) Q.pop(); 53 Q.push( a ); dist[s.x ][s.y]=0; 54 Q.push( Node(0,0) ); 55 56 while(!Q.empty() ) { 57 Node current = Q.front(); Q.pop(); 58 Node last_direct = Q.front(); Q.pop(); 59 60 for ( int i=0; i<4; ++i ){ 61 int xx = current.x+ step[i][0]; 62 int yy = current.y+ step[i][1]; 63 if(!ok(xx, yy) ) continue; 64 //cout <<xx << " " << yy << endl; 65 int d = dist[current.x][current.y]; 66 if(!is(last_direct, Node(step[i][0], step[i][1])) ) ++d; 67 68 if(is(Node(xx, yy), e ) ) { // 节点是终点 69 dist[xx][yy] = min(dist[xx][yy], d); 70 if(dist[xx][yy] < 4) return 1; 71 } 72 73 if(!g[xx][yy] && dist[xx][yy] > d){ 74 // 入队列的只能是空点,而且是距离更新过的 75 dist[xx][yy] = d; 76 if(d > 3) continue; 77 Q.push(Node(xx, yy) ); 78 Q.push(Node(step[i][0], step[i][1]) ); 79 } 80 } 81 } 82 return 0; 83 }; 84 85 void solve(){ 86 int q; scanf("%d", &q); 87 while( q-- ) { 88 s.scan(); e.scan(); 89 if( bfs(s, e) ) puts("YES"); 90 else puts("NO"); 91 } 92 } 93 int main(){ 94 while( scanf("%d%d", &n, &m), n||m ){ 95 init(); 96 solve(); 97 } 98 };
突然想起记录方向时直接用一个数值表示就号可以了,我代码中的记录方法麻烦。。