http://acm.hdu.edu.cn/showproblem.php?pid=1175
思路:枚舉一個和原點A橫座標或縱座標相同的一個轉折點B,根據目標點D和折點B得出另一個轉折點C.
A-->B-->C-->D如果這條路通了,就可以消除了。
import java.util.Scanner;public class Main{ static int a[][]=new int[1005][1005],m,n,ex,ey; public static void main(String[] args) { Scanner in=new Scanner(System.in); int q,i,j,k,x1,y1,x2,y2,x,y,xx,yy,flag; while(in.hasNextInt()) { n=in.nextInt(); m=in.nextInt(); if(n==0&&m==0) break; for(i=0;i<n;i++) for(j=0;j<m;j++) a[i][j]=in.nextInt(); q=in.nextInt(); while(q--!=0) { x1=in.nextInt()-1; y1=in.nextInt()-1; ex=x2=in.nextInt()-1; ey=y2=in.nextInt()-1; if(a[x1][y1]!=a[x2][y2]||x1==x2&&y1==y2||a[x1][y1]==0||a[x2][y2]==0) {System.out.println("NO");continue;} flag=0; lab:for(i=0;i<n;i++) //轉折點在行上 { if(i!=x1) { if(OK(x1,y1,i,y1)) //判斷當前點能不能直達轉折點 { //得到兩個轉折點 x=i; y=y1; xx=x; yy=y2; //x相同,y不同 if(OK(x,y,xx,yy)&&OK(xx,yy,x2,y2)) {flag=1;break lab;}//已配對 xx=x2; yy=y; //y相同,x不同 if(OK(x,y,xx,yy)&&OK(xx,yy,x2,y2)){flag=1;break lab;}//已配對 } } } lab1:for(j=0;j<m;j++) //轉折點在列上 { if(j!=y1) { if(OK(x1,y1,x1,j)) { x=x1; y=j; xx=x; yy=y2; if(OK(x,y,xx,yy)&&OK(x2,y2,xx,yy)) {flag=1;break lab1;}//已配對 xx=x2; yy=y; //y相同,x不同 if(OK(x,y,xx,yy)&&OK(x2,y2,xx,yy)){flag=1;break lab1;}//已配對 } } } if(flag==1) System.out.println("YES"); else System.out.println("NO"); } } } public static boolean OK(int x1,int y1,int x2,int y2) { int t,i; if(x1==x2) { if(y1>y2) {t=y2; y2=y1; y1=t;} else t=y2; for(i=y1+1;i<y2;i++) { if(a[x1][i]!=0) return false; } if((x1!=ex||t!=ey)&&a[x1][t]!=0) return false; } if(y1==y2) { if(x1>x2) {t=x2; x2=x1; x1=t;}else t=x2; for(i=x1+1;i<x2;i++) if(a[i][y1]!=0) return false; if((t!=ex||y2!=ey)&&a[t][y2]!=0) return false; } return true; }}