dfs剪枝 连连看 HDU - 1175

连连看 HDU - 1175

注意事项

1.剪枝,可以大大优化,判断转两个方向后与目标是否在同一直线上:

if (turn == 2 && tx - nowx && ty - nowy) return;  //剪枝

2.标记是否访问的时候注意写法:

vis[nextx][nexty] = true;
dfs(nextx, nexty, i, (tid == i || tid == -1) ? turn : turn + 1, tx, ty);
vis[nextx][nexty] = false;

参考代码

#include<stdio.h>
#include<iostream>
#include<vector>
#include<cstring>
#include<cstdio>
#include<climits>
#include<cmath>
#include<algorithm>
#include<queue>
#include<deque>
#include<map>
#include<set>
#include<stack>
#define LOCAL  //提交的时候一定注释
#define inf 0x3f3f3f3f
#define INF 0x3f3f3f3f3f3f3f3f
typedef long long LL;
typedef double db;
const db pi = acos(-1);
using namespace std;
const int maxn = 1010;

int readint() {
    
    
    int x; scanf("%d", &x); return x;
}

int M[maxn][maxn];
bool flag;
int n, m;
int dir[4][2] = {
    
    {
    
    1, 0}, {
    
    -1, 0}, {
    
    0, 1}, {
    
    0, -1}};
bool vis[maxn][maxn];

bool valid(int x, int y) {
    
    
    return x >= 0 && x < n && y >= 0 && y < m;
}

void init() {
    
    
    flag = false;
    memset(vis, 0, sizeof(vis));
}

void dfs(int nowx, int nowy, int tid, int turn, int tx, int ty) {
    
    
    if (flag || turn > 2) return;
    if (turn == 2 && tx - nowx && ty - nowy) return;  //剪枝
    if (nowx == tx && nowy == ty) {
    
    flag = true; return;}
    for(int i = 0; i < 4; i++) {
    
    
        int nextx = nowx + dir[i][0];
        int nexty = nowy + dir[i][1];
        if (valid(nextx, nexty) && !vis[nextx][nexty]) {
    
    
            if (M[nextx][nexty] && (nextx != tx || nexty != ty)) continue;
            vis[nextx][nexty] = true;
            dfs(nextx, nexty, i, (tid == i || tid == -1) ? turn : turn + 1, tx, ty);
            vis[nextx][nexty] = false;
        }
    }
}
int main() {
    
    
#ifdef LOCAL
    freopen("input.txt", "r", stdin);
//   freopen("output.txt", "w", stdout);
#endif
    int q;
    while (~scanf("%d%d", &n, &m) && n) {
    
    
        for(int i = 0; i < n; i++) {
    
    
            for(int j = 0; j < m; j++) {
    
    
                M[i][j] = readint();
            }
        }
        q = readint();
        int x1, y1, x2, y2;
        while (q--) {
    
    
            init();
            scanf("%d%d%d%d", &x1, &y1, &x2, &y2);
            x1--; y1--; x2--; y2--;  //转成从0开始标号
            vis[x1][y1] = true;
            if (M[x1][y1] == M[x2][y2] && M[x1][y1])
                dfs(x1, y1, -1, 0, x2, y2);
            printf("%s\n", flag ? "YES" : "NO");
        }

    }
    return 0;
}

猜你喜欢

转载自blog.csdn.net/Encore47/article/details/112976213