华容道!

QAQ
这道题目看上去感觉挺简单的,直接BFS暴力搜索应该就可以,
仔细一看数据范围
满分是不可能了,但应该能过60的数据,但是居然过了70的!
Orz
讲一下实现方法,队列有四个变量,分别表示白格子的位置以及移动棋子的具体位置,枚举白格子可以走的四个方向,当白格子与移动棋子发生位置交换时,要注意变换移动棋子的位置,使用一个四维数组来进行标记,要注意每次搜索时清空F数组
下面是代码

#include 
#include 
#include 
#include  
using namespace std;
int map[99][99];
int n,m,q;
int xmb,ymb;
struct tw{
    int x,y;
    int x1,y1;
    int step;
};
int minstep;
int x[4]=
{1,-1,0,0};
int y[4]=
{0,0,1,-1};
bool f[40][40][40][40];
tw opt;
int bfs()
{
    memset(f,0,sizeof(f));
    queue  dl;

    f[opt.x][opt.y][opt.x1][opt.y1]=1;
    dl.push(opt);

    while(!dl.empty())
    {
        tw o=dl.front();
        dl.pop();

        if(o.x1==xmb&&o.y1==ymb)
         return o.step;

        for(int i=0;i<=3;i++)
         {
            tw f1;
            f1.x=o.x+x[i];
            f1.y=o.y+y[i];

            if(f1.x==o.x1&&f1.y==o.y1)
             f1.x1=o.x,f1.y1=o.y;
            else
             f1.x1=o.x1,f1.y1=o.y1;

            f1.step=o.step+1;

            if(f1.x<1||f1.y<1||f1.x>n||f1.y>m||!map[f1.x][f1.y]) continue;

            if(!f[f1.x][f1.y][f1.x1][f1.y1])
            {
                f[f1.x][f1.y][f1.x1][f1.y1]=1;
                dl.push(f1);
            }
         }
    }
    return -1;
}
int main()
{
    scanf("%d%d%d",&n,&m,&q);

    for(int i=1;i<=n;i++)
     for(int j=1;j<=m;j++)
      scanf("%d",&map[i][j]);

    for(int i=1;i<=q;i++)
     {
        scanf("%d%d%d%d%d%d",&opt.x,&opt.y,&opt.x1,&opt.y1,&xmb,&ymb);
        opt.step=0;
        printf("%d\n",bfs());
     }

     return 0;
} 

你可能感兴趣的:(题目分析,BFS)