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

【算法】最少步数

亿万年的星光12个月前 (10-01)题解目录1195

【题目描述】

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

相关文章

【题解】小x与队列

【题目描述】小X正和同学们做列队的练习。有n名同学排成一路纵队,编号为i的同学排在从前往后数第i个位置上,即:初始时的队列为1, 2, 3, ..., n。接下来小X会发出若干条指令,每条指令形如“请...

【题解】切割钢管

【题解】切割钢管

【题目描述】小A是某工地的计算工程师。工地现有 n 根钢管,第 i 根钢管的长度为 ai。现在想用这 n 根钢管来做一个支撑用的柱子。我么可以切割这些钢管成为更短的钢管,但是不能缝合两根钢管。为了安全...

【题解】游戏

【题目描述】上了半天的物理数学课,大家的脑子有点转不动了,下午的课表似乎看透了同学们的 心思,第一节就安排了体育课,CZ 中学的课表真是太有爱了,赞一个!午间休息后,文体 委员小 S 喊大家到教室外的...

字符串移位包含问题

【题目描述】对于一个字符串来说,定义一次循环移位操作为:将字符串的第一个字符移动到末尾形成新的字符串。给定两个字符串 s_1s1 和 s_2s2,要求判定其中一个字符串是...

【题解】数学游戏

【题目描述】Kri 喜欢玩数字游戏。 一天,他在草稿纸上写下了t 对正整数(x,y) ,并对于每一对正整数计算出了z=x*y*gcd(x,y);可是调皮的 Zay 找到了 Kri 的草稿纸,并把每一...

简单算术表达式求值

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