BFS——1175连连看

1175连连看

请添加图片描述

文章目录


题意:

给出一个 n ∗ m n*m nm的棋盘,玩一个类似于连连看的游戏。

1 2 3 4
0 0 0 0
4 3 2 1

0 : 空 格 {\color{red}0:空格} 0
其 他 : 不 同 的 棋 子 {\color{red}其他:不同的棋子}
给定棋盘以后,给定起点 s t a r t x , s t a r t y start_x,start_y startx,starty和终点 e n d x , e n d y end_x,end_y endx,endy,要求从起点走到终点,方向转折的次数不能超过2次。

思路:

这题的限制不再是步数,而是转折次数,这就注定了我们不能和正常的bfs一样拓展。
那么该如何拓展呢,既然是以转折次数为限制,我们就一次性把一条直线上可以拓展的点全部拓展,具体见下图。

1 2 3 4
0 0 0 0
4 3 2 1
数字为转折次数,起点特殊记录为-1。
起点为 ( 1 , 1 ) (1,1) (1,1),终点为 ( 3 , 4 ) (3,4) (3,4)
请添加图片描述
请添加图片描述
请添加图片描述
请添加图片描述

每次都往四个方向进行直线拓展。
拓展部分代码示例如下:

for(int i = 0 ; i < 4 ; i++)
{
    int tx = temp.x + ne[i][0];
    int ty = temp.y + ne[i][1];
    while(OK(tx,ty))
    {
        que[++tail] = {tx,ty,temp.step+1};
        book[tx][ty] = true;
        tx += ne[i][0];
        ty += ne[i][1];
    }
}    

时间复杂度:

O ( n ∗ m ∗ q ) O(n*m*q) O(nmq)

AC代码:
在这里插入图片描述

#include<bits/stdc++.h>

typedef long long ll;

const int N = 1e3+10,M = 2e4+10,INF = 0x3f3f3f3f,mod = 1e9+7;
struct Node{
    int x,y,step;
}que[N*N];
int a[N][N];
bool book[N][N];
int ne[4][2] = {0,1,1,0,0,-1,-1,0};
int n,m,start_x,start_y,end_x,end_y;


bool OK(int x,int y)
{
    if(x==end_x&&y==end_y)return true;
    if(x < 1||y < 1||x > n||y > m||book[x][y]||a[x][y])return false;
    return true;
}

void bfs()
{
    for(int i = 1 ; i <= n ; i++)
        for(int j = 1 ; j <= m ; j++)book[i][j] = false;
    int head = 0,tail = -1;
    std::cin>>start_x>>start_y>>end_x>>end_y;
    if(a[start_x][start_y]!=a[end_x][end_y]||a[start_x][start_y]==0||a[end_x][end_y]==0)
    {
        std::cout<<"NO\n";
        return;
    }
    que[++tail] = {start_x,start_y,-1};
    book[start_x][start_y] = true;
    while(tail>=head)
    {
        auto temp = que[head++];
        if(temp.x == end_x && temp.y == end_y)
        {
            std::cout<<"YES\n";
            return;
        }
        if(temp.step==2)continue;
        for(int i = 0 ; i < 4 ; i++)
        {
            int tx = temp.x + ne[i][0];
            int ty = temp.y + ne[i][1];
            while(OK(tx,ty))
            {
                que[++tail] = {tx,ty,temp.step+1};
                book[tx][ty] = true;
                tx += ne[i][0];
                ty += ne[i][1];
            }
        }
    }
    std::cout<<"NO\n";
}

int main()
{
    std::ios::sync_with_stdio(false);
    std::cin.tie(nullptr);
    std::cout.tie(nullptr);
    while(std::cin>>n>>m)
    {
        if(n==0&&m==0)break;
        for(int i = 1 ; i <= n ; i++)
            for(int j = 1 ; j <= m ; j++)std::cin>>a[i][j];
        int q;
        std::cin>>q;
        while(q--)
        {
            bfs();
        }
    }
    return 0;
}

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值