洛谷 P1747 好奇怪的游戏 解题报告

题目描述

爱与愁大神坐在公交车上无聊,于是玩起了手机。一款奇怪的游戏进入了爱与愁大神的眼帘:***(游戏名被打上了马赛克)。这个游戏类似象棋,但是只有黑白马各一匹,在点x1,y1和x2,y2上。它们得从点x1,y1和x2,y2走到1,1。这个游戏与普通象棋不同的地方是:马可以走“日”,也可以像象走“田”。现在爱与愁大神想知道两匹马到1,1的最少步数,你能帮他解决这个问题么?

输入输出格式

输入格式:

第1行:两个整数x1,y1

第2行:两个整数x2,y2

输出格式:

第1行:黑马到1,1的距离

第2行:白马到1,1的距离

输入输出样例

输入样例#1:  复制
12 16
18 10
输出样例#1:  复制
8 
9

说明

100%数据:x1,y1,x2,y2<=20

读题再结合数据范围,很明显是一道搜索题,对于题目中说马可以走日也可以走田,画个图就知道

1 1 1 1

1       1

1       1

1 1 1 1

搜索方式变成了一个正方形而已

改动后的方向数组如下

int dx[]={-2,-1,1,2,-2,2,-2,2,-2,-1,1,2};
int dy[]={2,2,2,2,1,1,-1,-1,-2,-2,-2,-2};

再考虑怎么搜,dfs还是bfs,由于dfs会求出所有可能,所以dfs更适用于多结果的搜索,而bfs只是求一个最优解,故更适用于单结果搜索(然而很多搜索题bfs和dfs都可以做,选哪个差别不大,主要看个人喜好)

先说dfs的做法

先考虑起点,题目中说有两匹马,一开始准备要做两次搜索分别求解,但是后来发现题目可以转化为从终点出发到两匹马位置,就只要搜索一次,搜索时记录下从起点到每个点的距离,直接输出到两匹马的距离就好

代码如下

void dfs(int x,int y)
{
  
    if(a[x][y]&&a[x][y]<=s)return;
    a[x][y]=s;++s;
    for(int i=0;i<12;i++)
       {
        int xx=x+dx[i],yy=y+dy[i];    
        if(xx>=1&&yy>=1&&xx<=20&&yy<=20&&!vis[xx][yy])
        {
            vis[x][y]=1;
            dfs(xx,yy);
            vis[x][y]=0;
            }    
            }
    --s;        
}

再说bfs的做法,思路同上,转化为从终点出发到两匹马位置,其实这道题bfs比dfs更好,因为求最短路径时bfs可以确保第一次出最优解,效率更高

代码如下

void bfs(int x,int y)
{
    int h=0,t=1;
    que[t][0]=x;
    que[t][1]=y;
    vis[x][y]=1;
    while(h<t)
    {
        h++;
        for(int i=0;i<12;i++)
        {
        int xx=que[h][0]+dx[i],yy=que[h][1]+dy[i];
           if(xx>=1&&yy>=1&&xx<=20&&yy&&!vis[xx][yy])
             {
                t++;
                que[t][0]=xx;
                que[t][1]=yy;
                vis[xx][yy]=1;    
                a[xx][yy]=a[que[h][0]][que[h][1]]+1;    
                    }
            
            }
    }

完整代码如下

#include<bits/stdc++.h>
using namespace std;
int x1,y11,x2,y2,s,a[25][25],que[10005][3];
int dx[]={-2,-1,1,2,-2,2,-2,2,-2,-1,1,2};
int dy[]={2,2,2,2,1,1,-1,-1,-2,-2,-2,-2};
bool vis[25][25];
/*void dfs(int x,int y)
{
    
    if(a[x][y]&&a[x][y]<=s)return;
    a[x][y]=s;++s;
    for(int i=0;i<12;i++)
       {
        int xx=x+dx[i],yy=y+dy[i];    
        if(xx>=1&&yy>=1&&xx<=20&&yy<=20&&!vis[xx][yy])
        {
            vis[x][y]=1;
            dfs(xx,yy);
            vis[x][y]=0;
            }    
            }
    --s;        
}*/
void bfs(int x,int y)
{
    int h=0,t=1;
    que[t][0]=x;
    que[t][1]=y;
    vis[x][y]=1;
    while(h<t)
    {
        h++;
        for(int i=0;i<12;i++)
        {
        int xx=que[h][0]+dx[i],yy=que[h][1]+dy[i];
           if(xx>=1&&yy>=1&&xx<=20&&yy&&!vis[xx][yy])
             {
                t++;
                que[t][0]=xx;
                que[t][1]=yy;
                vis[xx][yy]=1;    
                a[xx][yy]=a[que[h][0]][que[h][1]]+1;    
                    }
            
            }
    }
    
}
int main()
{
    cin>>x1>>y11>>x2>>y2;
//    dfs(1,1);
    bfs(1,1);
    cout<<a[x1][y11]<<endl<<a[x2][y2];
    return 0;
}

dfs部分参考大佬@小菜鸟题解

猜你喜欢

转载自www.cnblogs.com/pcpcppc/p/9328322.html
今日推荐