hdu 1175 连连看
一个早上了,整整一个早上了,我的天啊,错误是大把大把的
可是思路明明很简单,这题是用BFS做的,可是不能紧紧标记一个点是否已经访问过,这样直接WA,因为访问过的不符合条件的点,很可能是因为转了太多的弯,但完全有可能存在转的弯比较少的路径在之后访问该点,所以vis[][]数组是用来保存访问过该点的最少的转弯次数,这样,只要访问该点,该点的转弯次数小于之前访问该店的最小转弯次数,则可以入队
我很不明白,我之前有些为什么还会MLE……
#include <iostream> #define MAXN 1001 #include <queue> using namespace std; int map[MAXN][MAXN]; int vis[MAXN][MAXN]; int n, m, sx, sy, ex, ey, q; //int mov[ 4 ][ 2 ] = {{1, 0}, {-1, 0}, {0, -1}, {0, 1}}; //搜索的顺序影响结果 int dir[ 4 ][ 2 ] = {{0, 1}, {1, 0}, {0, -1}, {-1, 0}}; struct node { int x; int y; int turn; int dir; }; void BFS() { queue<node> Q; node p, q; p.x = sx; p.y = sy; vis[ sx ][ sy ] = 0; p.dir = -1; p.turn = 0; Q.push(p); while(!Q.empty()) { q = Q.front(); Q.pop(); if(q.x == ex && q.y == ey) { cout<<"YES"<<endl; return ; } //0下, 1上, 2左, 3右 for(int i = 0; i < 4; ++ i) { p.x = q.x + dir[ i ][ 0 ]; p.y = q.y + dir[ i ][ 1 ]; p.turn = q.turn; p.dir = q.dir; if(q.dir == -1){ p.dir = i; p.turn = 0; } else if(q.dir != i) { p.turn ++; p.dir = i; } if(p.x < 1 || p.x > n || p.y < 1 || p.y > m) continue; if(map[ p.x ][ p.y ] && !(p.x == ex && p.y == ey) || p.turn > 2) continue; if(vis[ p.x ][ p.y ] > p.turn) { vis[ p.x ][ p.y ] = p.turn; Q.push(p); } } } cout<<"NO"<<endl; } void res() { scanf("%d", &q); while(q --) { scanf("%d %d %d %d", &sx, &sy, &ex, &ey); if(sx == ex && sy == ey) { cout<<"NO"<<endl; continue; } if(map[ sx ][ sy ] != map[ ex ][ ey ] || map[ sx ][ sy ] == 0 || map[ ex ][ ey ] == 0) { cout<<"NO"<<endl; continue; } for(int i = 1; i <= n; ++ i) { for(int j = 1; j <= m; ++ j) { vis[ i ][ j ] = INT_MAX; } } BFS(); } } int main() { while(scanf("%d %d", &n, &m)) { if(n == 0 && m == 0) break; for(int i = 1; i <= n; ++ i) { for(int j = 1; j <= m; ++ j) { scanf("%d", &map[ i ][ j ]); } } res(); } return 0; }