hdu1175: 连连看(bfs)

http://acm.hdu.edu.cn/showproblem.php?pid=1175

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

解题思路:

如果起点和终点的数值不同或者两者都为0时时不能消去的。

用四个变量分别存储坐标,方向,和转弯次数,只走值为0或终点位置,如果转弯次数大于2,舍去,同时更新到达某一步的最小转弯次数。

#include <stdio.h>
#include <string.h>
#include <algorithm>
#include <math.h>
#include <queue>
using namespace std;
#define N 1020
int a[N][N], book[N][N];
struct data
{
	int x;
	int y;
	int t;
	int f;
}s,r;

int main()
{	
	int next[5][2]={0,0, -1,0, 0,1, 1,0, 0,-1};
	int n, m, i, j, T, x1, x2, y1, y2, head, tail, tx, ty;
	while(scanf("%d%d", &n, &m)!=EOF)
	{
		if(n==0 && m==0)
			break;
		for(i=1; i<=n; i++)
			for(j=1; j<=m; j++)
				scanf("%d", &a[i][j]);
		scanf("%d", &T);
		while(T--)
		{	
			queue<data>q;
			scanf("%d%d%d%d", &x1, &y1, &x2, &y2);
			if(a[x1][y1]!=a[x2][y2] || a[x1][y1]==0)
			{
				printf("NO
");
				continue;
			}
			memset(book, 10, sizeof(book));
			head=0;
			tail=1;
			s.x=x1;
			s.y=y1;
			s.t=0;
			s.f=0;
			q.push(s);
			while(!q.empty())
			{
				s=q.front();
				q.pop();
				if(s.x==x2 && s.y==y2)
				{
					if(book[x2][y2]<=2)
						break;
					continue;
				}
				for(i=1; i<=4; i++)
				{
					tx=s.x+next[i][0];
					ty=s.y+next[i][1];
					if(tx<1 || ty<1 || tx>n || ty>m || (a[tx][ty]!=0 && !(tx==x2 && ty==y2)))
						continue;
	
					r.x=tx;
					r.y=ty;
					r.f=i;
					if(r.f==s.f || s.f==0)
						r.t=s.t;
					else
						r.t=s.t+1;
					book[tx][ty]= min(book[tx][ty], r.t);
					if(r.t<=2 && r.t==book[tx][ty])
						q.push(r);
						
				}
				head++;
			}
	
			if(book[x2][y2]<=2)
				printf("YES
");
			else
				printf("NO
");
		}
	}
	return 0;
} 
原文地址:https://www.cnblogs.com/zyq1758043090/p/11852716.html