1. 程式人生 > >hdu 1175 連連看 DFS+剪枝

hdu 1175 連連看 DFS+剪枝

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

解題思路:

       先看起點終點是否為同一個數,是進入搜尋否則直接輸出NO。題目要求不能大於兩個轉彎,也就是路徑說只能有小於等於三條直線,把起點當成一條直線,然後每轉換一次方向在直線數加1,當路徑已經為三條直線時,看終點是否在第三條直線上,不在進行遞迴,直線數大於三的也不在進行遞迴。如果能找到終點輸出YES。

程式碼:

#include<stdio.h>
#include<string.h>
#define N 1010
int m,n,flag,x1,x2,y1,y2;
int map[N][N],book[N][N];
void DFS(int x,int y,int c,int f)
{
	int i,j;
	int next[4][2]={{0,1},{1,0},{0,-1},{-1,0}};
	if(flag==1)
		return ;
	if(c>3)  //大於三條直線,題目要求不能大於兩個轉彎,也就是路徑說只能有小於等於三條直線 
	{
		return ;
	}
	if(c==3&&(x-x2)!=0&&(y-y2)!=0) //此時終點應該在第三條直線上 
	{
		return ;
	}	
	if(x==x2&&y==y2)  //找打終點 
	{	
		flag=1;
		return ;
	}
	for(i=0;i<4;i++)
	{
		int tx=x+next[i][0];
		int ty=y+next[i][1];
		if(tx>m||tx<1||ty>n||ty<1)
			continue;
		if((map[tx][ty]==0||tx==x2&&ty==y2)&&book[tx][ty]==0)
		{
			//printf("**%d %d %d\n",tx,ty,c);
			book[tx][ty]=1;
			if(f!=i)   //開始f定義10,起點算一條線 ,每轉一次彎加一條線 
			{
				DFS(tx,ty,c+1,i);
			}
			else
			{
				DFS(tx,ty,c,i);
			}
			book[tx][ty]=0;
		}
	}
	return ;
}
int main()
{
	int i,j,t;
	while(scanf("%d%d",&m,&n),m+n!=0)
	{
		for(i=1;i<=m;i++)
		{
			for(j=1;j<=n;j++)
			{
				scanf("%d",&map[i][j]);
			}
		}
		scanf("%d",&t);
		
		while(t--)
		{
			flag=0;
			memset(book,0,sizeof(book));
			scanf("%d%d%d%d",&x1,&y1,&x2,&y2);
			if(map[x1][y1]==map[x2][y2]&&map[x1][y1]!=0&&map[x2][y2]!=0)
			{	//起點終點的代表的數一樣(不等於0)進入搜尋,否則直接輸出NO 
				DFS(x1,y1,0,10);
			}
			if(flag==1)
				printf("YES\n");				
			else
				printf("NO\n");
		}
	}
	return 0;
}


相關推薦

hdu 1175 連連 DFS+剪枝

Problem Description “連連看”相信很多人都玩過。沒玩過也沒關係,下面我給大家介紹一下游戲規則:在一個棋盤中,放了很多的棋子。如果某兩個相同的棋子,可以通過一條線連起來(這條線不能經過其它棋子),而且線的轉折次數不超過兩次,那麼這兩個棋子就可以在棋盤上消

HDU-1175 連連

Problem Description “連連看”相信很多人都玩過。沒玩過也沒關係,下面我給大家介紹一下游戲規則:在一個棋盤中,放了很多的棋子。如果某兩個相同的棋子,可以通過一條線連起來(這條線不能經過其它棋子),而且線的轉折次數不超過兩次,那麼這兩個棋子就可以在棋盤上消去

hdu 1175 連連(搜尋)

上週實驗課上學妹問我的題目,當時我寫了個dfs,結果一直爆棧。今天又把程式碼重新看了一下,程式碼有一些小問題,修改之後又加了兩個剪枝A掉。 #include<stdio.h> #include<string.h> #define N 1005 in

【2018多校Beautiful Now HDU - 6351】【dfs+剪枝

【連結】 http://acm.hdu.edu.cn/showproblem.php?pid=6351 【題意】 大意就是給你一個數n,求在最多k次得交換下,能夠得到的最大的數和最小得數是多少,且數不能有前導0 【分析】 數的大小不超過1e9,也就是9位數字。 顯然地,n個數

1175 連連

“連連看”相信很多人都玩過。沒玩過也沒關係,下面我給大家介紹一下游戲規則:在一個棋盤中,放了很多的棋子。如果某兩個相同的棋子,可以通過一條線連起來(這條線不能經過其它棋子),而且線的轉折次數不超過兩次,那麼這兩個棋子就可以在棋盤上消去。不好意思,由於我以前沒有玩過連連看,諮詢

HDU 6351 Beautiful Now DFS+剪枝

Problem Description Anton has a positive integer n, however, it quite looks like a mess, so he wants to make it beautiful after k swaps o

HDOJ 1175 連連 廣度優先搜尋

Problem Description “連連看”相信很多人都玩過。沒玩過也沒關係,下面我給大家介紹一下游戲規則:在一個棋盤中,放了很多的棋子。如果某兩個相同的棋子,可以通過一條線連起來(這條線不能經過其它棋子),而且線的轉折次數不超過兩次,那麼這兩個棋子就可以在棋盤上消

HDU 1175DFS+剪枝

很有意思的一題哈…… (寫完了把每次錯的就改正了重新提交我可去你的吧=A=) 看完題目硬是想不出怎麼判斷轉了一個彎 紫書上也有轉彎的題但是感覺和這個不一樣…… 剪枝和象棋那個題有點像很好理解 煩的是莫名其妙的WA(死在粗心打錯看不到) 內容很簡單很普通的DFS…

hdu 1455 sticks【dfs】+經典剪枝

ems clas .net tdi pac target 構建 algorithm stream 題目鏈接:https://vjudge.net/problem/HDU-1455 轉載於:>>>>>> 題目大意: George把一些等長的

hdu - 1072(dfs剪枝

space sin else 題目 ios class pan using cstring 題目鏈接:http://acm.hdu.edu.cn/showproblem.php?pid=1072 思路:深搜每一個節點,並且進行剪枝,記錄每一步上一次的s1,s2;如果之前走過

Hdu 6341 Problem.J Let Sudoku Rotate(dfs+剪枝

題意就是給你一個已經解完的數獨,但是他的某幾塊被逆時針旋轉過幾次,問你最小的旋轉次數。 當時比賽的時候,因為被題面嚇到了,以為是難題,就沒有仔細思考,現在看看,就是一道搜尋題,用bfs和dfs都可以過。 一開始想著如果用bfs的話,可能還要存下每旋轉一次的狀態,會顯得很繁瑣,就沒有選擇bfs

Hdu 6341 Problem J. Let Sudoku Rotate 暴力dfs+剪枝

Problem J. Let Sudoku Rotate Input file: standard input Output file: standard output Time limit: 2 seconds Memory l

HDU 1010 Tempter of the Bone (DFS+剪枝(奇偶剪枝原理))

題意: 根據地圖,'S'為開始位置,'D'為門的位置,' . '為空地,'X'為牆,不能經過, 問:在指定的時間,是否能到達'門'的位置. 注意:路不可以重複經過,時間也要剛好是 t ,不能少. 思路: 因為是查詢距離為t的路徑,所以不能用bfs。樸素的dfs肯定會TLE,這裡需

hdu 5167 Fibonacci(DFS剪枝,斐波那契)

Fibonacci Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/65536 K (Java/Others) Total Submission(s): 2391    Accepted Sub

hdu 1190 生日蛋糕(dfs+剪枝

Description 7月17日是Mr.W的生日,ACM-THU為此要製作一個體積為Nπ的M層生日蛋糕,每層都是一個圓柱體。  設從下往上數第i(1 <= i <= M)層蛋糕是半徑為Ri, 高度為Hi的圓柱。當i < M時,要求Ri > Ri

dfs(hdu1175 連連

連連看Time Limit: 20000/10000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others)Total Submission(s): 40217    Accepted Submission(

hdu 蜘蛛牌(DFS + 剪枝)

Problem Description 蜘蛛牌是windows xp作業系統自帶的一款紙牌遊戲,遊戲規則是這樣的:只能將牌拖到比她大一的牌上面(A最小,K最大),如果拖動的牌上有按順序排好的牌時,那麼這些牌也跟著一起移動,遊戲的目的是將所有的牌按同一花色從小到大排好,為了簡

1月 D - 逃離迷宮 HDU - 1728-復雜dfs剪枝

pri 出發 col else 數據 手動 測試數據 while 包含 給定一個m × n (m行, n列)的迷宮,迷宮中有兩個位置,gloria想從迷宮的一個位置走到另外一個位置,當然迷宮中有些地方是空地,gloria可以穿越,有些地方是障礙,她必須繞行,從迷宮

HDU 1455 Sticks(DFS剪枝,原來木棒的至少長度)

Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others) Total Submission(s): 9115    Accepted Submission(

hdu 6031 Innumerable Ancestors(LCA+剪枝)

line show view i++ code dfs 過去 rabl using 題目鏈接:hdu 6031 Innumerable Ancestors 題意: 給你一棵n個節點的樹,現在有m個詢問,每次給你兩個點集a,b。 讓你從a,b點集中選兩個點x,y,使得這兩個點