hdoj--1175 连连看(dfs)

来源:互联网 发布:h5 banner轮播js源码 编辑:程序博客网 时间:2024/05/16 19:46

link to problem

题解

判断两点是否连通,多了一个转向次数不超过两次的条件。
嗯,,还可以继续优化。。

#include <iostream>#include <cstdio>#include <cstring>#include <algorithm>#include <vector>using namespace std;const int maxn = 1000 + 4;const int dx[] = {0, 0, 1, -1};const int dy[] = {1, -1, 0, 0};int a[maxn][maxn];bool vis[maxn][maxn];int n, m;int q, x1, y1, x2, y2, t;// 从(x, y)开始搜索,搜索方向dir, 当前转向次数dircntbool dfs(int x, int y, int dir, int dircnt){    if(dircnt > 2) return false;    if(dircnt == 2){ // 加入优化,当转向达到2次后,不再转向 4290MS   4708K        int nx = x + dx[dir], ny = y + dy[dir];        if(1 <= nx && nx <= n && 1 <= ny && ny <= m && !vis[nx][ny] ){            if(nx == x2 && ny == y2) return true;            if(a[nx][ny]) return false;            vis[nx][ny] = true;            if(dfs(nx, ny, dir, dircnt)) return true;            vis[nx][ny] = false;        }    }    else{ // 7534MS 4712K        for(int i = 0; i < 4; ++i){            int nx = x + dx[i], ny = y + dy[i], t = dircnt;            if(1 <= nx && nx <= n && 1 <= ny && ny <= m && !vis[nx][ny]){                if(dir != -1 && dir != i) t++;  // 判断是否转向                if(nx == x2 && ny == y2) return t <= 2;                if(a[nx][ny]) continue;                vis[nx][ny] = true;                if(dfs(nx, ny, i, t)) return true;                vis[nx][ny] = false;            }        }    }    return false;}int main(){#ifdef EXMYfreopen("data.in", "r", stdin);#endif // EXMY    while(cin >> n >> m && n){        for(int i = 1; i <= n; ++i){            for(int j = 1; j <= m; ++j) scanf("%d", &a[i][j]);        }        cin >> q;        while(q--){            scanf("%d %d %d %d", &x1, &y1, &x2, &y2);            memset(vis, 0, sizeof(vis));            bool flag = ((x1 != x2 || y1 != y2) && a[x1][y1] && a[x2][y2] && a[x1][y1] == a[x2][y2]);            if(flag && dfs(x1, y1, -1, 0)) printf("YES\n");            else printf("NO\n");        }    }    return 0;}
0 0