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

【算法】最少步数

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

【题目描述】

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

字符串反连接

【题目描述】写一函数,使输入的一个字符串按反序存放,在主函数中输入并输出反序后的字符串(不包含空格)。【输入描述】一行字符【输出描述】逆序后的字符串【样例输入】123456abcdef【样例输出】fe...

【题解】建设病房

1.建设病房(build.cpp)【题目描述】2020年1月23日下午,武汉市建设局紧急召集中建三局等单位举行专题会议,要求参照2003年抗击非典期间北京小汤山医院模式,在武汉职工疗养院建设火神山医院...

【题解】结构体与闰年

【题目描述】定义一个结构体变量(包括年、月、日)。计算该日在本年中是第几天,注意闰年问题。【输入描述】年月日【输出描述】当年第几天【样例输入】2000 12 31【样例输出】366...

【题解】放苹果(1)

【题目描述】把M个同样的苹果放在N个同样的盘子里,允许有的盘子空着不放,问共有多少种不同的分法?(用K表示)5,1,1和1,5,1 是同一种分法。【输入】第一行是测试数据的数目t(0≤t≤20)。以下...