zoukankan      html  css  js  c++  java
  • 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;
    } 
  • 相关阅读:
    Spring boot返回值封装与业务异常
    Spring boot日志
    Rocket项目启动
    抉择
    C# 字符转ASCII码,ASCII码转字符 [转一下]
    xcode 学习笔记2:动态添加view
    unrecognized selector sent to instance 0x1b97e0' 问题解决记录
    xcode 学习笔记1:Interface Builder的使用
    xcode 学习笔记4:给WindowBase程序添加view
    xcode 学习笔记3:xcode目录结构
  • 原文地址:https://www.cnblogs.com/zyq1758043090/p/11852715.html
Copyright © 2011-2022 走看看