当前位置:首页 > 题解目录 > 正文内容

【算法】最少步数

亿万年的星光3年前 (2023-10-01)题解目录3055

【题目描述】

在各种棋中,棋子的走法总是一定的,如中国象棋中马走“日”。有一位小学生就想如果马能有两种走法将增加其趣味性,因此,他规定马既能按“日”走,也能如象一样走“田”字。他的同桌平时喜欢下围棋,知道这件事后觉得很有趣,就想试一试,在一个(100×100)的围棋盘上任选两点A、B,A点放上黑子,B点放上白子,代表两匹马。棋子可以按“日”字走,也可以按“田”字走,俩人一个走黑马,一个走白马。谁用最少的步数走到左上角坐标为(1,1)的点时,谁获胜。现在他请你帮忙,给你A、B两点的坐标,想知道两个位置到(1,1)点可能的最少步数。

【输入描述】

A、B两点的坐标。

【输出描述】

最少步数

【样例输入】

12 16
18 10

【样例输出】

8
9

【题目分析】

  • 跟“马走日”类似,可以用dfs或者bfs。本文选用的bfs,用 数组+结构体 模拟队列。

  • 注意题目要求是求最小步数。

  • 本题不考虑初始状态就是目标坐标的情况。


(1)初始状态,头指针和尾指针处于同一个位置(同一个点,初始状态尾指针加1,准备存储新数据)。


(2) 如果遇到合适的点(坐标),尾指针加1,把当前节点存入到队列中,队列会变长。(假如这一轮中只有3个点满足条件)

(3)然后头节点加1(head++),判断是否到达目标 点,如果到达就输出步数,终止循环。如果没有,就以2这个点为基础,继续遍历。

假如以2这个点为基础遍历,有2个点是满足题目要求的,那么图像应该变成下面这样:


(4)继续上面3这个步骤,知道遇到第一个满足条件的点,就是题目的解。



【参考代码】

#include<bits/stdc++.h> 
using namespace std;
int a[105][105];
bool flag[105][105]; //标记数组 
//偏移数组 
int dir[][2]={{-2,1},{-2,-1},
			  {-2,2},{-2,-2},
			  {-1,-2},{-1,2},
			  {1,-2},{1,2},
			  {2,-1},{2,1},
			  {2,-2},{2,2}
			 };
			 
struct maps 
{
    int x;
    int y; //x,y坐标 
    int step; //步数 
};
maps  q[100100];
void bfs(int x0,int y0)
{
    int head=1,tail=1; //头指针,尾指针 
    memset(flag,0,sizeof(flag)); //初始化标记数组 
    
    q[tail].x=x0;
    q[tail].y=y0;  //起点坐标赋值给尾指针 
    q[tail].step=0;
    tail++; //尾节点加1,准备读入新值 
    flag[x0][y0]=1; //标记当前节点为使用状态 
	while(head<tail) 
    {
        int x=q[head].x; //初次的head值就是x0,y0 
        int y=q[head].y;
        int step=q[head].step;
        if(x==1&&y==1)
        {
            cout<<step<<endl;
            break;
        }
        for(int i=0;i<12;i++)  //一共12种情况 
        {
            int nx=x+dir[i][0]; //当前x坐标加x的偏移量 
            int ny=y+dir[i][1]; //当前y坐标加y的偏移量 
            if(nx>=1&&nx<=100&&ny>=1&&ny<=100&&flag[nx][ny]==0) //是否满足条件 
            {
                flag[nx][ny]=1;
                q[tail].x=nx;
                q[tail].y=ny;
                q[tail].step=step+1;
                tail++;
            }
        }
        head++;
    }
}
int main()
{
    int xa,ya,xb,yb;
    cin>>xa>>ya>>xb>>yb; 
    bfs(xa,ya); //遍历第一组
    bfs(xb,yb); //遍历第二组 
    return 0;
}


    扫描二维码推送至手机访问。

    版权声明:本文由青少年编程知识记录发布,如需转载请注明出处。

    标签: dfsbfs
    分享给朋友:

    相关文章

    【题解】东哥的杯子

    【题解】东哥的杯子

    【题目描述】话说在一场牛客练习赛中,东哥力压群雄,挣得第一,牛客为了奖励东哥的发挥,送他一个马克杯。奖励的马克杯是一个标准的圆台形状,它的上底为R1,下底为R2,高为H, 东哥向杯子里倒V毫升的水,你...

    【题解】阶乘的末尾

    【题目描述】n的阶乘定义为n!=1*2*3*……*n  如3!=6   n!通常最后会有很多0,如5!=120  最后有一个0,现在统计n!去除末尾的0后,最后k位是多少...

    【题解】Power Strings

    【题目描述】给定若干个长度 ≤106 的字符串,询问每个字符串最多是由多少个相同的子字符串重复连接而成的。如:ababab 则最多有 3 个 ab 连接而成。【输入描述】输入若干行,每行有一...

    合影效果

    【题目描述】小云和朋友们去爬香山,为美丽的景色所陶醉,想合影留念。如果他们站成一排,男生全部在左(从拍照者的角度),并按照从矮到高的顺序从左到右排,女生全部在右,并按照从高到矮的顺序从左到右排,请问他...

    【题解】合根植物

    【题解】合根植物

    【题目描述】w星球的一个种植园,被分成 m * n 个小格子(东西方向m行,南北方向n列)。每个格子里种了一株合根植物。这种植物有个特点,它的根可能会沿着南北或东西方向伸展,从而与另一个格子的植物合成...

    简单算术表达式求值

    【题目描述】 两位正整数的简单算术运算(只考虑整数运算),算术运算为:+,加法运算;    -,减法运算;   &nbs...