HDU 1175 连连看(BFS)

题意解析:其实就是判断起始点能否到达终止点。如果起始点和终止点值不同,直接输出NO。bfs,dfs都行。

附加条件:①不能出边界

②不能走值为0的点

③路径不能转向两次以上

节点需要记录该点的坐标,方向,转向次数。下面是BFS代码(注意剪枝:超过两次的就不要再加入队列了)

#include<iostream>
#include<cstdio>
#include<queue>
#define M 1005
using namespace std;

int G[M][M];
int Hash[M][M]; //记录某条路径在该点转向的次数
int dir[4][2]={{-1,0},{0,-1},{1,0},{0,1}};
int n,m;
struct Node
{
    int x,y,d,turn;
};
queue<Node>q;

bool bfs(int x1,int y1,int x2,int y2)
{
    Node p,t;
    while(!q.empty()){
        p=q.front();
        q.pop();
        if(p.x==x2&&p.y==y2&&p.turn<=2) return true; //满足条件
        for(int i=0;i<4;i++){
            t.x=p.x+dir[i][0];
            t.y=p.y+dir[i][1];
            if(t.x<1||t.y<1||t.x>n||t.y>m) continue; //出边界情况
            if(p.d==i){
                t.turn=p.turn;
                t.d=p.d;
            }
            else{
                t.turn=p.turn+1;
                t.d=i;
            }
            if(t.turn>2) continue; //转向次数超过两次的(剪枝)
            if((!G[t.x][t.y]||(t.x==x2&&t.y==y2))&&Hash[t.x][t.y]>=t.turn){
                q.push(t);
                Hash[t.x][t.y]=t.turn;
            }
        }
    }
    return false;
}

int main()
{
    //freopen("d:\\Test.txt","r",stdin);
    int x1,x2,y1,y2;
    while(scanf("%d%d",&n,&m)&&(n||m)){
        for(int i=1;i<=n;i++){
            for(int j=1;j<=m;j++){
                scanf("%d",&G[i][j]);
            }
        }
        int Q;
        scanf("%d",&Q);
        for(int i=0;i<Q;i++){
            scanf("%d%d%d%d",&x1,&y1,&x2,&y2);
            if(G[x2][y2]!=G[x1][y1]||G[x1][y1]==0||G[x2][y2]==0||(x1==x2&&y1==y2)){
                cout<<"NO"<<endl;
                continue;
            }
            for(int i=1;i<=n;i++){
                for(int j=1;j<=m;j++){
                    Hash[i][j]=11;//初始为较大的数即可
                }
            }
            Hash[x1][y1]=0; //出发点
            while(!q.empty()) q.pop();
            Node t;
            //初始出发点4个方向的值
            for(int i=0;i<4;i++){
                t.d=i;
                t.turn=0;
                t.x=x1;
                t.y=y1;
                q.push(t);
            }
            if(bfs(x1,y1,x2,y2)) cout<<"YES"<<endl;
            else cout<<"NO"<<endl;
        }
    }
    return 0;
}
时间: 2024-12-20 03:00:12

HDU 1175 连连看(BFS)的相关文章

HDU 1175 连连看 (BFS带方向的判定)

连连看 Time Limit: 20000/10000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others)Total Submission(s): 23172    Accepted Submission(s): 5710 Problem Description “连连看”相信很多人都玩过.没玩过也没关系,下面我给大家介绍一下游戏规则:在一个棋盘中,放了很多的棋子.如果某两个相同的棋子,可以通过一条线连起来(这条线不能经过其

HDU 1175 连连看(bfs + 剪枝)

Problem Description: "连连看"相信很多人都玩过.没玩过也没关系,下面我给大家介绍一下游戏规则:在一个棋盘中,放了很多的棋子.如果某两个相同的棋子,可以通过一条线连起来(这条线不能经过其它棋子),而且线的转折次数不超过两次,那么这两个棋子就可以在棋盘上消去.不好意思,由于我以前没有玩过连连看,咨询了同学的意见,连线不能从外面绕过去的,但事实上这是错的.现在已经酿成大祸,就只能将错就错了,连线不能从外围绕过. 玩家鼠标先后点击两块棋子,试图将他们消去,然后游戏的后台判

hdu 1175 连连看(模拟循环队列)

连连看 Time Limit: 20000/10000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others) Total Submission(s): 18149    Accepted Submission(s): 4741 Problem Description "连连看"相信很多人都玩过.没玩过也没关系,下面我给大家介绍一下游戏规则:在一个棋盘中,放了很多的棋子.如果某两个相同的棋子,可以通过一条线连起来(这条

HDU - 1175 连连看 DFS (记录方向)

连连看HDU - 1175 "连连看"相信很多人都玩过.没玩过也没关系,下面我给大家介绍一下游戏规则:在一个棋盘中,放了很多的棋子.如果某两个相同的棋子,可以通过一条线连起来(这条线不能经过其它棋子),而且线的转折次数不超过两次,那么这两个棋子就可以在棋盘上消去.不好意思,由于我以前没有玩过连连看,咨询了同学的意见,连线不能从外面绕过去的,但事实上这是错的.现在已经酿成大祸,就只能将错就错了,连线不能从外围绕过. 玩家鼠标先后点击两块棋子,试图将他们消去,然后游戏的后台判断这两个方格能

【dfs】hdu 1175 连连看

[dfs]hdu 1175 连连看 题目链接:hdu 1175 连连看 题目大意 连连看,问能否成功? 题意很简单,就是我们平时玩的连连看的游戏规则,貌似dfs和bfs都能做,笔者就做了个dfs(好想),超时了好几次,原因是dfs(int d)与终点的d重载矛盾了,所以还是要小心. 说一下思路 神器的剪枝:if(t==2&&x!=c&&y!=d) return;这一部剪枝妙笔回春,9000+MS优化到100+MS啊:如果转了2次,但是目标与当前位置不在同一行或同一列就不满足

hdu 1175 连连看 (深搜)

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1175 题目大意:如果某两个相同的棋子,可以通过一条线连起来(这条线不能经过其它棋子)这样的两个棋子可以消掉.还有一个要注意的地方的就是转弯.转弯的次数不超过两次,这两个棋子才可以在棋盘上消去~ 1 #include <iostream> 2 #include <cstdio> 3 #include <cstring> 4 using namespace std; 5 int

hdu - 1728逃离迷宫 &amp;&amp; hdu - 1175 连连看 (普通bfs)

http://acm.hdu.edu.cn/showproblem.php?pid=1728 这两道题花了一下午的时候调试,因为以前做过类似的题,但是判断方向的方法是错的,一直没发现啊,真无语. 每个状态除了坐标外还需要记录步数,和方向.还要注意输入格式. 并且每一个点并不是走过了就不能在走,只要到达这个点的时候转向次数少的就可以更新这个点,可以等于.千万注意这个坑. 1 #include <cstdio> 2 #include <cstring> 3 #include <q

HDU 1175 连连看(BFS)

Problem Description “连连看”相信很多人都玩过.没玩过也没关系,下面我给大家介绍一下游戏规则:在一个棋盘中,放了很多的棋子.如果某两个相同的棋子,可以通过一条线连起来(这条线不能经过其它棋子),而且线的转折次数不超过两次,那么这两个棋子就可以在棋盘上消去.不好意思,由于我以前没有玩过连连看,咨询了同学的意见,连线不能从外面绕过去的,但事实上这是错的.现在已经酿成大祸,就只能将错就错了,连线不能从外围绕过.玩家鼠标先后点击两块棋子,试图将他们消去,然后游戏的后台判断这两个方格能

HDU 1175 连连看【BFS】

题意:给出起点和终点的棋子,不能经过别的棋子,而且转弯的次数不能超过2次,问能否消除 和逃离迷宫一样,每个节点记录下来它的当前的方向和转弯的次数,再搜 注意特判起点的棋子和终点的棋子为0或者不一样的情况,这样的话就不用搜了,直接输出NO 1 #include<iostream> 2 #include<cstdio> 3 #include<cstring> 4 #include <cmath> 5 #include<stack> 6 #includ