HDU-1175 連連看
阿新 • • 發佈:2018-12-14
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
思路:基本的dfs,注意剪枝,要不然會超時。
程式碼:
#include <stdio.h> #include <string.h> int e[1010][1010]; int book[1010][1010]; int flag; int d1[8]={-1,0,1,0}; int d2[8]={0,1,0,-1}; int n,m,x2,y2; void dfs(int x,int y,int d,int t) { int tx,ty,i; if(t>2||flag==1) return ; if(t==2&&(x-x2)!=0&&(y-y2)!=0)//剪枝,判斷轉彎兩次之後與目標點在不在一條直線上 return ; if(x==x2&&y==y2&&t<=2) { flag=1; return ; } for(i=0;i<4;i++) { tx=x+d1[i]; ty=y+d2[i]; if(tx<1||ty<1||tx>n||ty>m) continue; if(e[tx][ty]==0||(tx==x2&&ty==y2)) { book[tx][ty]=1; if(d==-1||d==i) dfs(tx,ty,i,t); else dfs(tx,ty,i,t+1); book[tx][ty]=0; } } } int main() { int x1,y1; int q,t,i,j; while(scanf("%d%d",&n,&m)!=EOF) { if(n==0&&m==0) break; memset(e,0,sizeof(e)); for(i=1;i<=n;i++) for(j=1;j<=m;j++) scanf("%d",&e[i][j]); scanf("%d",&q); for(i=1;i<=q;i++) { flag=0; scanf("%d%d%d%d",&x1,&y1,&x2,&y2); memset(book,0,sizeof(book)); if(e[x1][y1]==e[x2][y2]&&e[x1][y1]!=0) dfs(x1,y1,-1,0); if(flag==1) printf("YES\n"); else printf("NO\n"); } } return 0; }