HDU 1175 连连看 dfs+剪枝
生活随笔
收集整理的這篇文章主要介紹了
HDU 1175 连连看 dfs+剪枝
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
點擊打開鏈接
連連看
Time Limit: 20000/10000 MS (Java/Others)????Memory Limit: 65536/32768 K (Java/Others)Total Submission(s): 40337????Accepted Submission(s): 9971
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
Author lwg
Recommend We have carefully selected several similar problems for you:??1180?1072?1016?1026?1010
思路:
定義函數時注意設計參數:dfs(x,y,dic,turns);x,y為當前搜索起點
dic為當前前進方向
turns為當前轉彎數
剪枝:第二次轉彎后,判斷與目標是否在同一條直線上
前進方向:
AC代碼:#include <iostream> #include <cstdio> #include <cstring> using namespace std;int maze[1010][1010]; bool vis[1010][1010]; int sx,sy,ex,ey; bool flag; int n,m,q; /* int dicx[]={1,-1,0,0}; int dicy[]={0,0,1,-1}; */ int to[4][2]={{0,-1},{-1,0},{0,1},{1,0}}; void dfs(int x,int y,int dic,int turns){if(turns>2||flag) return;//轉彎次數大于2或者已經找到就終止if(turns==2&&(x-ex)!=0&&(y-ey)!=0) return;//剪枝:判斷兩次轉彎后是否與目標在同一直線上if(x==ex&&y==ey&&turns<=2){//搜索終點flag=1;return;}/*for(int i=0;i<4;++i){//搜索四個方向int xx=x+dicx[i];int yy=y+dicy[i];if(xx<1||xx>n||yy<1||yy>m||vis[xx][yy]) continue;//邊界情況if(maze[xx][yy]==0||(xx==ex&&yy==ey)){vis[xx][yy]=1;if(dic==-1||dic==i)//如果在起點或者同向的情況turns不變及不轉向,并將當前方向記為idfs(xx,yy,i,turns);elsedfs(xx,yy,i,turns+1);//否則turns+1vis[xx][yy]=0;}}*/for(int i=0;i<4;++i){//搜索四個方向int xx=x+to[i][0];int yy=y+to[i][1];if(xx<1||xx>n||yy<1||yy>m||vis[xx][yy]) continue;//邊界情況if(maze[xx][yy]==0||(xx==ex&&yy==ey)){vis[xx][yy]=1;if(dic==-1||dic==i)//如果在起點或者同向的情況turns不變及不轉向,并將當前方向記為idfs(xx,yy,i,turns);elsedfs(xx,yy,i,turns+1);//否則turns+1vis[xx][yy]=0;}}return; }int main(){while(~scanf("%d%d",&n,&m)){if(n==0&&m==0)break;memset(maze,0,sizeof(maze));for(int i=1;i<=n;++i)for(int j=1;j<=m;++j)scanf("%d",&maze[i][j]);scanf("%d",&q);for(int i=0;i<q;++i){scanf("%d%d%d%d",&sx,&sy,&ex,&ey);memset(vis,0,sizeof(vis));flag=0;//初始化if(maze[sx][sy]==maze[ex][ey]&&maze[sx][sy])dfs(sx,sy,-1,0);//將初始方向設為-1if(flag) printf("YES\n");else printf("NO\n");}}return 0; }
總結
以上是生活随笔為你收集整理的HDU 1175 连连看 dfs+剪枝的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: Fibonacci数列 矩阵快速幂
- 下一篇: HDU 6186 CS Course