Time Limit: 20000/10000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others)
Total Submission(s): 5387 Accepted Submission(s): 1401
3 4 1 2 3 4 0 0 0 0 4 3 2 1 4 1 1 3 4 1 1 2 4 1 1 3 3 2 1 2 4 3 4 0 1 4 3 0 2 4 1 0 0 0 0 2 1 1 2 4 1 3 2 3 0 0
YES NO NO NO NO YES
#include <iostream> #include <stdio.h> #include <memory.h> using namespace std; int n, m, t, k, z; int x1, y1, x2, y2; int a[1005][1005]; bool map[1005][1005], flag; void init() //初始化函数 { flag = false; memset(map, false, sizeof(map)); } void dfs(int x, int y, int z, int k) //坐标(x,y) { if(flag) return; if(x<=0 || y<=0 || x>n || y>m) return; //若超界,返回 if(k>=3) return; //若转弯数已经超过3次,返回 if(x == x2 && y == y2) { flag = true; return; } if(k == 2) //超强剪枝:若已经转两次弯,则目标坐标必须要在前进方向的前面,否则直接返回 { if( !(z==1 && x>x2 && y==y2 || z==2 && x<x2 && y==y2 || z==3 && y>y2 && x==x2 || z==4 && y<y2 && x==x2) ) return; } if(a[x][y] != 0) return; //如果该点不是0,则不能走,返回 if(map[x][y]) return; //如果该点已经走过,返回 map[x][y] = true; //标记该点为走过 if(z == 1) //上 { dfs(x-1, y, 1, k); dfs(x+1, y, 2, k+1); dfs(x, y-1, 3, k+1); dfs(x, y+1, 4, k+1); } else if(z == 2) //下 { dfs(x-1, y, 1, k+1); dfs(x+1, y, 2, k); dfs(x, y-1, 3, k+1); dfs(x, y+1, 4, k+1); } else if(z == 3) //左 { dfs(x-1, y, 1, k+1); dfs(x+1, y, 2, k+1); dfs(x, y-1, 3, k); dfs(x, y+1, 4, k+1); } else if(z == 4) //右 { dfs(x-1, y, 1, k+1); dfs(x+1, y, 2, k+1); dfs(x, y-1, 3, k+1); dfs(x, y+1, 4, k); } map[x][y] = false; //若深搜不成功,标记该点为未走过 } int main() { int i, j; while(scanf("%d %d", &n, &m)) { if(!n && !m) break; for(i = 1; i <= n; i++) for(j = 1 ; j <= m; j++) scanf("%d", &a[i][j]); scanf("%d", &t); for(i = 0; i < t; i++) { init(); scanf("%d %d %d %d", &x1, &y1, &x2, &y2); if(x1 == x2 && y1 == y2 && a[x1][y1] != 0) //若两点坐标是相同的,输出NO printf("NO\n"); else if(a[x1][y1] == a[x2][y2] && a[x1][y1] != 0) //若两点的值相同且不为0 { dfs(x1-1, y1, 1, 0); dfs(x1+1, y1, 2, 0); dfs(x1, y1-1, 3, 0); dfs(x1, y1+1, 4, 0); if(flag) printf("YES\n"); else printf("NO\n"); } else printf("NO\n"); } } return 0; }