注意事项
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;
}