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;
}

posted @ 2011-08-10 12:48  枕边梦  阅读(252)  评论(1编辑  收藏  举报