Luogu P1979 华容道

题目描述

小 B 最近迷上了华容道,可是他总是要花很长的时间才能完成一次。于是,他想到用编程来完成华容道:给定一种局面, 华容道是否根本就无法完成,如果能完成, 最少需要多少时间。

小 B 玩的华容道与经典的华容道游戏略有不同,游戏规则是这样的:

  1. 在一个 n \times mn×m 棋盘上有n \times mn×m个格子,其中有且只有一个格子是空白的,其余n \times (m-1)n×(m−1)个格子上每个格子上有一个棋子,每个棋子的大小都是 1 \times 11×1 的;

  2. 有些棋子是固定的,有些棋子则是可以移动的;

  3. 任何与空白的格子相邻(有公共的边)的格子上的棋子都可以移动到空白格子上。

游戏的目的是把某个指定位置可以活动的棋子移动到目标位置。

给定一个棋盘,游戏可以玩 qq 次,当然,每次棋盘上固定的格子是不会变的, 但是棋盘上空白的格子的初始位置、 指定的可移动的棋子的初始位置和目标位置却可能不同。第 ii 次玩的时候, 空白的格子在第 EX_iEXi​ 行第 EY_iEYi​列,指定的可移动棋子的初始位置为第 SX_iSXi​ 行第 SY_iSYi​列,目标位置为第 TX_iTXi​ 行第 TY_iTYi​ 列。

假设小 B 每秒钟能进行一次移动棋子的操作,而其他操作的时间都可以忽略不计。请你告诉小 B 每一次游戏所需要的最少时间,或者告诉他不可能完成游戏。

输入输出格式

输入格式:

 

第一行有 33个整数,每两个整数之间用一个空格隔开,依次表示n,m,qn,m,q;

接下来的 nn 行描述一个n \times mn×m 的棋盘,每行有mm个整数,每两个整数之间用一个空格隔开,每个整数描述棋盘上一个格子的状态,00 表示该格子上的棋子是固定的,11 表示该格子上的棋子可以移动或者该格子是空白的。

接下来的 qq 行,每行包含 66 个整数依次是 EX_i,EY_i,SX_i,SY_i,TX_i,TY_iEXi​,EYi​,SXi​,SYi​,TXi​,TYi​,每两个整数之间用一个空格隔开,表示每次游戏空白格子的位置,指定棋子的初始位置和目标位置。

 

输出格式:

 

共qq 行,每行包含 11 个整数,表示每次游戏所需要的最少时间,如果某次游戏无法完成目标则输出$−1$。

 

输入输出样例

输入样例#1: 复制

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

输出样例#1: 复制

2
-1

说明

【输入输出样例说明】

棋盘上划叉的格子是固定的,红色格子是目标位置,圆圈表示棋子,其中绿色圆圈表示目标棋子。

  1. 第一次游戏,空白格子的初始位置是 (3,2)(3,2)(图中空白所示),游戏的目标是将初始位置在(1, 2)(1,2)上的棋子(图中绿色圆圈所代表的棋子)移动到目标位置(2, 2)(2,2)(图中红色的格子)上。

移动过程如下:

  1. 第二次游戏,空白格子的初始位置是(1, 2)(1,2)(图中空白所示),游戏的目标是将初始位置在(2, 2)(2,2)上的棋子(图中绿色圆圈所示)移动到目标位置 (3, 2)(3,2)上。

要将指定块移入目标位置,必须先将空白块移入目标位置,空白块要移动到目标位置,必然是从位置(2,2)(2,2)上与当前图中目标位置上的棋子交换位置,之后能与空白块交换位置的只有当前图中目标位置上的那个棋子,因此目标棋子永远无法走到它的目标位置, 游戏无法完成。

【数据范围】

对于30\%30%的数据,1 ≤ n, m ≤ 10,q = 11≤n,m≤10,q=1;

对于 60\%60%的数据,1 ≤ n, m ≤ 30,q ≤ 101≤n,m≤30,q≤10;

对于 100\%100%的数据,1 ≤ n, m ≤ 30,q ≤ 5001≤n,m≤30,q≤500。

 

暴力搜70分,卡一卡就可以AC了

bfs记空白块与目标棋子

#include<cstdio>
using namespace std;
int read()
{
    int ret=0;
    char ch=getchar();
    while(ch<'0'||ch>'9') ch=getchar();
    while(ch>='0'&&ch<='9')
        ret=(ret<<1)+(ret<<3)+ch-'0',
        ch=getchar();
    return ret; 
}
const int N=35,M=1e6+5;
int n,m,t,l,r,ans,x1,y1,x2,y2,xx,yy;
int a[N][N],q1[M],q2[M],q3[M],q4[M],q5[M],fl[N][N][N][N];
  
int main()
{
    n=read(),m=read(),t=read();
    for(int i=1;i<=n;i++)
        for(int j=1;j<=m;j++)
            a[i][j]=read(); 
    for(int T=1;T<=t;T++)
    {
        x1=read(),y1=read(),x2=read(),y2=read(),xx=read(),yy=read(); 
        l=r=1;
        q1[1]=x1,q2[1]=y1,q3[1]=x2,q4[1]=y2;
        fl[x1][y1][x2][y2]=T;
        ans=1e9;
        while(l<=r)
        {
            int u=q1[l],v=q2[l],uu=q3[l],vv=q4[l];
            if(uu==xx&&vv==yy) 
            {
                ans=q5[l]; break;
            }
            if(fl[uu][vv][u][v]!=T&&(u-1==uu&&v==vv||u+1==uu&&v==vv||u==uu&&v-1==vv||u==uu&&v+1==vv))
            {
                fl[uu][vv][u][v]=T;
                q1[++r]=uu,q2[r]=vv,q3[r]=u,q4[r]=v;q5[r]=q5[l]+1;
            }
            if(u!=n&&fl[u+1][v][uu][vv]!=T&&a[u+1][v]&&(u+1!=uu||v!=vv))
            {
                fl[u+1][v][uu][vv]=T;
                q1[++r]=u+1,q2[r]=v,q3[r]=uu,q4[r]=vv,q5[r]=q5[l]+1;
            }
            if(u!=1&&fl[u-1][v][uu][vv]!=T&&a[u-1][v]&&(u-1!=uu||v!=vv))
            {
                fl[u-1][v][uu][vv]=T;
                q1[++r]=u-1,q2[r]=v,q3[r]=uu,q4[r]=vv,q5[r]=q5[l]+1; 
            }
              
            if(v!=m&&fl[u][v+1][uu][vv]!=T&&a[u][v+1]&&(u!=uu||v+1!=vv))
            {
                fl[u][v+1][uu][vv]=T;
                q1[++r]=u,q2[r]=v+1,q3[r]=uu,q4[r]=vv,q5[r]=q5[l]+1;
            }
            if(v!=1&&fl[u][v-1][uu][vv]!=T&&a[u][v-1]&&(u!=uu||v-1!=vv))
            {
                fl[u][v-1][uu][vv]=T;
                q1[++r]=u,q2[r]=v-1,q3[r]=uu,q4[r]=vv,q5[r]=q5[l]+1; 
            }
            l++;
        }
        if(ans==1e9) puts("-1");
            else printf("%d\n",ans);     
    }
    return 0;
}

 

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值