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

【算法】最少步数

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

【题目描述】

在各种棋中,棋子的走法总是一定的,如中国象棋中马走“日”。有一位小学生就想如果马能有两种走法将增加其趣味性,因此,他规定马既能按“日”走,也能如象一样走“田”字。他的同桌平时喜欢下围棋,知道这件事后觉得很有趣,就想试一试,在一个(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
分享给朋友:

相关文章

【题解】光荣的梦想

【题目描述】Prince对他在这片大陆上维护的秩序感到满意,于是决定启程离开艾泽拉斯。在他动身之前,Prince决定赋予King_Bette最强大的能量以守护世界、保卫这里的平衡与和谐。在那个时代,平...

【题解】2001-T1 数的计数

【题目描述】我们要求找出具有下列性质数的个数(包含输入的自然数nn):先输入一个自然数n(n≤1000)n(n≤1000),然后对此自然数按照如下方法进行处理:1.不作任何处理;2.在它的左边加上一个...

【题解】同学的等待

【题目描述】同学们下课后去食堂,每个人都需要一段时间去点菜。然而,某些同学点菜时间太长了。同学们对于等待很烦躁:他们希望,能尽量少的花时间等待。(同学数<=100000),(0<=点菜耗时...

【题解】数字的选择

【题目描述】有n个非负整数,请从这n个非负整数中,选出m个数,在不改变m个数的顺序的情况下,构成一个新数列,要求该数列的中相邻两个数的差值绝对值的和尽可能小。请问,这个最小的差值绝对值的和是多少?比如...

【题解】公路乘车(动态规划)

【题目描述】一个特别的单行街道在每公里处有一个汽车站。顾客根据他们乘坐汽车的公里使来付费。例如下表就是一个费用的单子。   没有一辆车子行驶超过10公里,一个顾客打算行驶n公里(1<...

【题解】开花

【题解】开花

【题目描述】小A所在的学校又迎来了一年一度的开花活动,有 n 名学生被评为文学优秀奖,m 名学生被评为体育优秀奖。现已知两个奖项获奖同学的编号,每个同学都有唯一的编号。只有同时被评为文学优秀奖和体育优...