Lianliankan HDU-1175 (Breadth First Search bfs)

This is a search question link

Lianliankan

I believe many people have played "Lianliankan". It doesn't matter if you haven't played, let me introduce the rules of the game to you: on a chessboard, there are a lot of chess pieces. If two identical pieces can be connected by a line (this line cannot pass through other pieces), and the number of turns of the line does not exceed twice, then these two pieces can be eliminated on the board. I'm sorry, because I haven't played Lianliankan before and consulted with my classmates, the connection cannot be bypassed from outside, but in fact this is wrong. Now that it has caused a catastrophe, you can only make mistakes, and the connection cannot be surrounded from the outside.

The player clicks on two chess pieces one after another with the mouse, trying to eliminate them, and then the background of the game determines whether the two squares can be eliminated. Now your task is to write this background program.
This background program.

There
are multiple groups of Input data. The first row of each group of data has two positive integers n, m (0<n<=1000, 0<m<1000), which respectively represent the number of rows and columns of the chessboard. In the next n rows, each row has m non-negative integers describing the grid distribution of the chessboard. 0 means that there is no pawn at this position, and a positive integer indicates the type of pawn. The next line is a positive integer q (0<q<50), indicating that there are q queries below. In the next q rows, there are four positive integers x1, y1, x2, y2 in each row, which means to ask whether the pieces in the x1 row and y1 column and the pieces in the x2 row and y2 column can be eliminated. When n=0, m=0, the input ends.

Note: There is no prioritization between the inquiries, they are all for the current state!

Output
of each set of input data corresponding to one line of output. If it can be eliminated, it will output "YES", if it cannot, it will output "NO".

Sample Input3 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 OutputYES
NO
NO
NO
NO
YES

At the beginning, I used a deep search to write this question, but of course it timed out. With Guangsou, the main idea is to record how many turns when you reach this point, which direction you are from when you come to this point, and the marker array no longer records whether you have been there, but records all the points where you have visited The minimum number of turns.

Code

#include<stdio.h>
#include<bits/stdc++.h>
using namespace std;
struct muban
{
    
    
 	int x;
 	int y;
 	int zh;
 	int turn;
 } s,temp;
int a[1005][1005];
int book[1005][1005];
int go[4][2]={
    
    {
    
    0,1},{
    
    1,0},{
    
    -1,0},{
    
    0,-1}};
int flag,n,m;
int bfs(int p,int q,int g,int h)
{
    
    
 	memset(book,15,sizeof(book));
 	int i;
 	queue <muban> qq;
 	s.x=p;
 	s.y=q;
 	s.zh=0;
 	s.turn=-1;
 	qq.push(s);
 	while(!qq.empty())
 	{
    
    
  		s=qq.front();
  		qq.pop();
  		if(s.x==g&&s.y==h&&s.zh<=2)
  		return 1;
  		for(i=0;i<4;i++)
  		{
    
    
   			temp=s;
   			temp.x=temp.x+go[i][0];
   			temp.y=temp.y+go[i][1];
   			if(temp.x>=1&&temp.x<=n&&temp.y>=1&&temp.y<=m&&(a[temp.x][temp.y]==0||(temp.x==g&&temp.y==h)))
   			{
    
    
    				if(temp.turn!=-1)
    				{
    
    
     					if(temp.turn!=i)
     					{
    
    
      						temp.turn=i;
      						temp.zh++;
     					}
    				}
    				else
    				temp.turn=i;
    				if(temp.zh>2)
    				continue;
    				if(temp.zh<=book[temp.x][temp.y])
    				{
    
    
     					book[temp.x][temp.y]=temp.zh;
     					qq.push(temp);
    				}
   			}
  		}
 	}
 	return 0;
}
int main()
{
    
    
 	while(scanf("%d%d",&n,&m)!=EOF&&n!=0&&m!=0)
 	{
    
    
  		int i,j;
  		for(i=1;i<=n;i++)
  		{
    
    
  			for(j=1;j<=m;j++)
   			{
    
    
    				scanf("%d",&a[i][j]);
   			}
  		}
  		int xun;
 		scanf("%d",&xun);
  		while(xun--)
  		{
    
    
   			int p,q,g,h;
   			flag=1;
   			scanf("%d%d%d%d",&p,&q,&g,&h);
   			if(a[p][q]!=a[g][h])//要先排除起点终点不同
   			flag=0;
   			if(a[p][q]==0||a[g][h]==0)//排除起点或终点为0的
   			flag=0;
   			if(p==g&&q==h)//排除起点终点相同的
   			flag=0;
   			if(flag==1)
   			flag=bfs(p,q,g,h);//进入广搜
   			if(flag)
   			printf("YES\n");
   			else
   			printf("NO\n");
  		}
 	}
 	return 0;
}

Guess you like

Origin blog.csdn.net/Huo6666/article/details/105591674