HDU 1175 连连看
连连看
Time Limit: 20000/10000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others)
Total Submission(s): 38048 Accepted Submission(s):
9447
Problem Description
“连连看”相信很多人都玩过。没玩过也没关系,下面我给大家介绍一下游戏规则:在一个棋盘中,放了很多的棋子。如果某两个相同的棋子,可以通过一条线连起来(这条线不能经过其它棋子),而且线的转折次数不超过两次,那么这两个棋子就可以在棋盘上消去。不好意思,由于我以前没有玩过连连看,咨询了同学的意见,连线不能从外面绕过去的,但事实上这是错的。现在已经酿成大祸,就只能将错就错了,连线不能从外围绕过。
玩家鼠标先后点击两块棋子,试图将他们消去,然后游戏的后台判断这两个方格能不能消去。现在你的任务就是写这个后台程序。
玩家鼠标先后点击两块棋子,试图将他们消去,然后游戏的后台判断这两个方格能不能消去。现在你的任务就是写这个后台程序。
Input
输入数据有多组。每组数据的第一行有两个正整数n,m(0<n<=1000,0<m<1000),分别表示棋盘的行数与列数。在接下来的n行中,每行有m个非负整数描述棋盘的方格分布。0表示这个位置没有棋子,正整数表示棋子的类型。接下来的一行是一个正整数q(0<q<50),表示下面有q次询问。在接下来的q行里,每行有四个正整数x1,y1,x2,y2,表示询问第x1行y1列的棋子与第x2行y2列的棋子能不能消去。n=0,m=0时,输入结束。
注意:询问之间无先后关系,都是针对当前状态的!
注意:询问之间无先后关系,都是针对当前状态的!
Output
每一组输入数据对应一行输出。如果能消去则输出"YES",不能则输出"NO"。
Sample Input
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
Sample Output
YES
NO
NO
NO
NO
YES
AC代码:
通用版
1 #include<iostream> 2 #include<fstream> 3 #include<stack> 4 using namespace std; 5 struct pot 6 { 7 int x,y,zhe,dir; 8 }; 9 const int MAX_ZHE=2;//转折次数 10 const int MAX=1005; 11 int arr[MAX][MAX]; 12 int dir[4][2]={{0,-1},{-1,0},{0,1},{1,0}}; 13 int result(int x1,int y1,int x2,int y2) 14 { 15 if(arr[x1][y1]==0||arr[x2][y2]==0||arr[x1][y1]!=arr[x2][y2]) 16 return 0; 17 stack<pot> sta; 18 pot cur={x1,y1,0,0}; 19 sta.push(cur); 20 int flag=0; 21 while(!sta.empty()) 22 { 23 cur=sta.top(); 24 sta.pop(); 25 if(flag==0)//第一个点 26 { 27 for(int i=0;i<4;i++) 28 { 29 pot next={cur.x+dir[i][0],cur.y+dir[i][1],0,i}; 30 if(arr[next.x][next.y]==-1) 31 continue; 32 if(next.x==x2&&next.y==y2) 33 return 1; 34 if(arr[next.x][next.y]==0)//空格,进一步,压栈处理 35 { 36 next.zhe=cur.zhe; 37 next.dir=i+1; 38 sta.push(next); 39 } 40 } 41 flag=1; 42 continue; 43 } 44 for(int i=0;i<4;i++) 45 { 46 pot next={cur.x+dir[i][0],cur.y+dir[i][1],0,i}; 47 if(arr[next.x][next.y]==-1) 48 continue; 49 if(cur.dir==i+1)//同向 50 { 51 if(next.x==x2&&next.y==y2) 52 return 1; 53 if(arr[next.x][next.y]==0)//空格,进一步,压栈处理 54 { 55 next.zhe=cur.zhe; 56 next.dir=i+1; 57 sta.push(next); 58 } 59 } 60 else if((cur.dir+i+1)%2==0)//反向 61 continue; 62 else//变向 63 { 64 if(cur.zhe+1<=MAX_ZHE) 65 { 66 if(next.x==x2&&next.y==y2) 67 return 1; 68 if(arr[next.x][next.y]==0)//空格,进一步,压栈处理 69 { 70 next.zhe=cur.zhe+1; 71 next.dir=i+1; 72 sta.push(next); 73 } 74 } 75 } 76 } 77 } 78 return 0; 79 } 80 int main() 81 { 82 //ifstream in("data.txt"); 83 int n,m,i,j; 84 while(cin>>n>>m&&n) 85 { 86 for(i=1;i<=n;i++) 87 for(j=1;j<=m;j++) 88 cin>>arr[i][j]; 89 for(i=0;i<=n+1;i++) 90 { 91 arr[i][0]=-1; 92 arr[i][m+1]=-1; 93 } 94 for(j=0;j<=m+1;j++) 95 { 96 arr[0][j]=-1; 97 arr[n+1][j]=-1; 98 } 99 int q,x1,y1,x2,y2; 100 cin>>q; 101 while(q--) 102 { 103 cin>>x1>>y1>>x2>>y2; 104 if(result(x1,y1,x2,y2)==1) 105 cout<<"YES"; 106 else 107 cout<<"NO"; 108 cout<<endl; 109 } 110 } 111 return 0; 112 }
二次转折特殊版
1 #include<iostream> 2 #include<fstream> 3 #include<queue> 4 #include<string> 5 using namespace std; 6 const int MAX=1005; 7 struct pot 8 { 9 int x,y; 10 }; 11 int arr[MAX][MAX]; 12 int find(int x1,int y1,int x2,int y2,int n,int m) 13 { 14 int flag=0; 15 int i,j,k,temp; 16 if(arr[x1][y1]==0||arr[x2][y2]==0||arr[x1][y1]!=arr[x2][y2]) 17 return 0; 18 if(x1+y1+1==x2+y2) 19 return 1; 20 if(y1>y2) 21 { 22 temp=x1; x1=x2; x2=temp; 23 temp=y1; y1=y2; y2=temp; 24 } 25 int xmin,xmax,ymin,ymax; 26 if(x1==x2){ 27 if(y1>y2) {ymin=y2; ymax=y1;} 28 for(j=ymin+1;j<ymax;j++) if(arr[x1][j]>0) break; 29 if(j>=ymax) return 1; 30 } 31 if(y1==y2) 32 { 33 if(x1>x2) {xmin=x2; xmax=x1;} 34 for(i=xmin+1;i<xmax;i++) if(arr[i][y1]>0) break; 35 if(i>=xmax) return 1; 36 } 37 for(j=y1-1;j>=1;j--){ 38 if(arr[x1][j]>0) break; 39 if(x1<=x2) 40 { 41 for(i=x1+1;i<x2;i++) if(arr[i][j]>0) break; 42 if(i>=x2){ 43 for(k=y2-1;k>=j;k--) if(arr[i][k]>0) break; 44 if(k<j) return 1; 45 } 46 } 47 else 48 { 49 for(i=x1-1;i>x2;i++) if(arr[i][j]>0) break; 50 if(i<=x2){ 51 for(k=y2-1;k>=j;k--) if(arr[i][k]>0) break; 52 if(k<j) return 1; 53 } 54 } 55 } 56 for(j=y1+1;j<=m;j++){ 57 if(arr[x1][j]>0) break; 58 if(x1<=x2) 59 { 60 for(i=x1+1;i<x2;i++) if(arr[i][j]>0) break; 61 if(i>=x2){ 62 if(j<=y2){ 63 for(k=y2-1;k>=j;k--) if(arr[i][k]>0) break; 64 if(k<j) return 1; 65 }else{ 66 for(k=y2+1;k<=j;k++) if(arr[i][k]>0) break; 67 if(k>j) return 1; 68 } 69 } 70 } 71 else 72 { 73 for(i=x1-1;i>x2;i++) if(arr[i][j]>0) break; 74 if(i<=x2){ 75 if(j<=y2){ 76 for(k=y2-1;k>=j;k--) if(arr[i][k]>0) break; 77 if(k<j) return 1; 78 }else{ 79 for(k=y2+1;k<=j;k++) if(arr[i][k]>0) break; 80 if(k>j) return 1; 81 } 82 } 83 } 84 } 85 if(x1<=x2) 86 { 87 for(i=x1-1;i>=1;i--){ 88 if(arr[i][y1]>0) break; 89 for(j=y1+1;j<y2;j++) if(arr[i][j]>0) break; 90 if(j>=y2){ 91 for(k=x2-1;k>=i;k--) if(arr[k][j]>0) break; 92 if(k<i) return 1; 93 } 94 } 95 for(i=x1+1;i<=n;i++){ 96 if(arr[i][y1]>0) break; 97 for(j=y1+1;j<y2;j++) if(arr[i][j]>0) break; 98 if(j>=y2){ 99 if(i<=x2){ 100 for(k=x2-1;k>=i;k--) if(arr[k][j]>0) break; 101 if(k<i) return 1; 102 }else{ 103 for(k=x2+1;k<=i;k++) if(arr[k][j]>0) break; 104 if(k>i) return 1; 105 } 106 } 107 } 108 } 109 else 110 { 111 for(i=x1-1;i>=1;i--){ 112 if(arr[i][y1]>0) break; 113 for(j=y1+1;j<y2;j++) if(arr[i][j]>0) break; 114 if(j>=y2){ 115 if(i<=x2){ 116 for(k=x2-1;k>=i;k--) if(arr[k][j]>0) break; 117 if(k<i) return 1; 118 }else{ 119 for(k=x2+1;k<=i;k++) if(arr[k][j]>0) break; 120 if(k>i) return 1; 121 } 122 } 123 } 124 for(i=x1+1;i<=n;i++){ 125 if(arr[i][y1]>0) break; 126 for(j=y1+1;j<y2;j++) if(arr[i][j]>0) break; 127 if(j>=y2){ 128 for(k=x2+1;k<=i;k++) if(arr[k][j]>0) break; 129 if(k>i) return 1; 130 } 131 } 132 } 133 return 0; 134 } 135 int main() 136 { 137 //ifstream in("data.txt"); 138 int n,m; 139 queue<pot> que; 140 int dir[4][2]={{1,0},{0,1},{-1,0},{0,-1}}; 141 while(cin>>n>>m&&n&&m) 142 { 143 int i,j; 144 for(i=1;i<=n;i++) 145 for(j=1;j<=m;j++) 146 cin>>arr[i][j]; 147 int q,x1,y1,x2,y2,zhe; 148 cin>>q; 149 while(q--) 150 { 151 cin>>x1>>y1>>x2>>y2; 152 int result=find(x1,y1,x2,y2,n,m); 153 if(result==1) 154 cout<<"YES"; 155 else 156 cout<<"NO"; 157 cout<<endl; 158 } 159 } 160 return 0; 161 }