刚开始写的有点恶心,认为要分为三种情况,所以哗啦啦地写了两种。
写第三种的时候发现原来全部都可以归结为第三种,即用三根折线连起来的情况。
【思路】
首先,若两点坐标相同,返回NO。
若两点值不同,返回NO。
若有一个点为0,返回NO。
水平方向,分别从两个点向两边寻找最大的可占用的空间(为0的点),分别得到两个区间,然后取两个区间的交集。
枚举交集中的每两个在同一竖直方向的点,如果它们之间的点均为0,即可以连线,即表示两个原始的点可以相连,返回YES。
这种情况包括一根线和两根折线相连的情况。
如果水平方向不满足,则以同样的方法检查竖直方向。
如果能则返回YES,否则返回NO。
【代码】
#include <iostream> using namespace std; #define min(a,b) ((a)<=(b)?(a):(b)) #define max(a,b) ((a)>=(b)?(a):(b)) const int maxn = 1000; int map[maxn+5][maxn+5]; int x1, x2, y1, y2; int n, m; bool ok0() { if (x1==x2 && y1==y2) return false; else if (map[x1][y1]==0 || map[x2][y2]==0) return false; else if (map[x1][y1]==map[x2][y2]) return true; else return false; } void get(int l1, int r1, int l2, int r2, int &l, int &r) { if (r1>r2) { swap(r1, r2); swap(l1, l2); } if (r1<l2) { l = 0; r = -1; return; } r = r1; if (l1<l2) { l = l2; } else { l = l1; } } void getlr(int x, int y, int &l, int &r) { int i; l = r = y; for (i=y+1; i<m; i++) { if (map[x][i]!=0) { break; } } r = i-1; for (i=y-1; i>=0; i--) { if (map[x][i]!=0) { break; } } l = i+1; } void gettb(int x, int y, int &t, int &b) { int i; t = b = x; for (i=x+1; i<n; i++) { if (map[i][y]!=0) { break; } } b = i-1; for (i=x-1; i>=0; i--) { if (map[i][y]!=0) { break; } } t = i+1; } bool ok3() { int i, j; int l1, r1, l2, r2; int l, r; int a, b, c, d; a = min(y1, y2); b = max(y1, y2); c = min(x1, x2); d = max(x1, x2); getlr(x1, y1, l1, r1); getlr(x2, y2, l2, r2); get(l1, r1, l2, r2, l, r); for (j=l; j<=r; j++) { for (i=c+1; i<d; i++) { if (map[i][j]!=0) break; } if (i>=d) return true; } int t1, b1, t2, b2; int tp, bt; gettb(x1, y1, t1, b1); gettb(x2, y2, t2, b2); get(t1, b1, t2, b2, tp, bt); for (i=tp; i<=bt; i++) { for (j=a+1; j<b; j++) { if (map[i][j]!=0) break; } if (j>=b) return true; } return false; } bool ok() { if (!ok0()) return false; if (ok3()) return true; else return false; } int main() { int q; int i, j; while(scanf("%d %d", &n, &m)!=EOF) { if (n==0 && m==0) break; for (i=0; i<n; i++) { for (j=0; j<m; j++) scanf("%d", &map[i][j]); } scanf("%d", &q); for (i=0; i<q; i++) { scanf("%d %d %d %d", &x1, &y1, &x2, &y2); x1--;y1--;x2--;y2--; if (ok()) printf("YES\n"); else printf("NO\n"); } } return 0; }