首页 > 编程语言 >DFS算法模板(2488:A Knight's Journey)

DFS算法模板(2488:A Knight's Journey)

时间:2024-02-22 17:11:38浏览次数:31  
标签:2488 int Knight visit DFS ways && 棋盘 road

DFS算法(C++版本)

题目一:

链接:http://bailian.openjudge.cn/practice/2488/

image-20240222010104488

image-20240222011851328

解析思路:

骑士找路就是基本的DFS,用递归不断找到合适的路,找不到就回头直到找到合适的路。

该题难点:要是实现字典序,也就是同样的两种选择,要走到A1而不是B1。所以就有了{-1,-2},{1,-2},{-2,-1},{2,-1},{-2,1},{2,1},{-1,2},{1,2}寻路时走路的尝试走路顺序。注意:我的程序输入的行(m)是表示的数字,列(n)表示的是字母这也是为什么尝试走路的顺序是列小的排在前面优先选择。

代码思路:

根据每次输入的m和n构建棋盘,visit数组默认是全为0,visit数组是棋盘的位置是1,然后经过DFS,走过的棋盘点在visit数组对应的位置置为2,不走走过的棋盘点也就是visit数组是2的点。用road数组记录如果成功走完了棋盘的路径,如果road数组的元素个数不等于m*n(棋盘点的个数),输出impossible,否则输出road数组。完工!!!!!!!!!!!!!!!!!!!

代码实现:

#include<iostream>
#include<cstring>
using namespace std;
//骑士之旅     http://bailian.openjudge.cn/practice/2488/
//右(上)上 {1,2}  右(下)上 {2,1}
//右(上)下 {2,-1}  右(下)下 {1,-2}
//左(上)上 {-1,2}  左(下)上 {-2,1}
//左(上)下 {-2,-1} 左(下)下 {-1,-2}
char alf[27] = { '0','A','B','C','D','E','F','G','H','I','J','K','L','M','N','O','P','Q','R','S','T','U','V','W','X','Y','Z' };
int number[10] = { 0,1,2,3,4,5,6,7,8,9 };
int visit[11][11];//棋盘点    1表示棋盘   2走过的棋盘点 
int road[40];//走的路线   十位表示行   个位表示列 
int freq;//用于记录有多少次的输出 
int step = 0; //走过了多少步 
char re_sign;//0表示没走到头     1表示走到头了 
void ways(int i, int j, int m, int n)
{
    //走过的路 
    visit[i][j] = 2;
    road[step++] = (i + 1) * 10 + (j + 1);//除去i和j为0的情况 
    //走通了 
    if (step == m * n)
    {
        re_sign = 1;
        return;
    }

    //走路的操作
    // 数字+字母  字母的字典序优先(A7>B1)
    //{-1,-2},{1,-2},{-2,-1},{2,-1},{-2,1},{2,1},{-1,2},{1,2}
    if (i - 1 >= 0 && j - 2 >= 0 && visit[i - 1][j - 2] == 1)
        ways(i - 1, j - 2, m, n);
    if (i + 1 < m && j - 2 >= 0 && visit[i + 1][j - 2] == 1)
        ways(i + 1, j - 2, m, n);
    if (i - 2 >= 0 && j - 1 >= 0 && visit[i - 2][j - 1] == 1)
        ways(i - 2, j - 1, m, n);
    if (i + 2 < m && j - 1 >= 0 && visit[i + 2][j - 1] == 1)
        ways(i + 2, j - 1, m, n);
    if (i - 2 >= 0 && j + 1 < n && visit[i - 2][j + 1] == 1)
        ways(i - 2, j + 1, m, n);
    if (i + 2 < m && j + 1 < n && visit[i + 2][j + 1] == 1)
        ways(i + 2, j + 1, m, n);
    if (i - 1 >= 0 && j + 2 < n && visit[i - 1][j + 2] == 1)
        ways(i - 1, j + 2, m, n);
    if (i + 1 < m && j + 2 < n && visit[i + 1][j + 2] == 1)
        ways(i + 1, j + 2, m, n);    


    if (re_sign == 1)
    {
        return;
    }
    //路走不通,把road还原(waiting) 
    visit[i][j] = 1;//恢复棋盘点 
    road[--step] = 0;//把原来记录走路的点恢复,再Sn减1==现走了几步	 

}
int main()
{
    //要将要输入几组数据 
    int t;
    cin >> t;
    while (t--)
    {
        int m, n;
        cin >> m >> n;// m  字母(A B C D) n 数字(1 2 3 4) 
        cout << "Scenario #" << ++freq << ":" << endl; //打印序号 
        if (m == 0 && n == 0)//输入错误信息
        {
            cout << "这样子的棋盘不存在" << endl;
            continue;
        }
        //初始化
        step = 0;
        re_sign = 0;
        memset(road, 0, sizeof(road));
        memset(visit, 0, sizeof(visit));
        //只考虑在A1开始寻路的情况 
        for (int i = 0; i < m; ++i)
        {
            for (int j = 0; j < n; ++j)
            {
                visit[i][j] = 1;
            }
        }
        ways(0, 0, m, n);//起始点开始DFS 

        //结果输出
        if (step == m * n)
        {
            for (int i = 0; i < step; i++)
            {
                //输出走过的路
                cout << alf[road[i] % 10] << number[road[i] / 10];
            }   
            cout << endl<<endl;
        }
        else
        {
            cout << "impossible"<<endl<<endl;
        }
    }

}

运行结果:

image-20240222012659635

标签:2488,int,Knight,visit,DFS,ways,&&,棋盘,road
From: https://www.cnblogs.com/study-sheep/p/18027720

相关文章

  • #根号分治,分块,dfs序#洛谷 7710 [Ynoi2077] stdmxeypz
    题目传送门分析首先把距离变成深度,用dfs序转成区间问题,考虑分块,散块直接改问题是整块,如果模数比较大,可以以深度为第一维下标差分标记,这样查询时就可以前缀和知道答案如果模数比较小,那么给该块打标记,查询时枚举模数即可,然后块长取1000,模数阈值取300,就能尽量减少时间代码#in......
  • 力扣 dfs之 437. 路径总和 III
    给定一个二叉树的根节点root ,和一个整数targetSum,求该二叉树里节点值之和等于targetSum的路径的数目。路径不需要从根节点开始,也不需要在叶子节点结束,但是路径方向必须是向下的(只能从父节点到子节点)。 示例1:输入:root=[10,5,-3,3,2,null,11,3,-2,null,1],target......
  • fastDFS:fdfs_monitor:last_heart_beat_time 字段的信息来自最后访问的tracker server的
    命令:fdfs_monitor/etc/fdfs/client.conf2>/dev/null|grep-vE'succ|out_'|grep-E'tracker|Stora|Group|heart|sync|time|id|ip|upload'结果: 说明:    last_heart_beat_time的指的是storageserver与trackerserver心跳通讯,收到的trackerserver的心......
  • fastDFS:优化参数配置,让dfs集群更灵敏
    【storage.conf】配置文件#connecttimeoutinseconds#defaultvalueis30#Note:intheintranetnetwork(LAN),2secondsisenough.connect_timeout=2#networktimeoutinsecondsforsendandrecv#defaultvalueis30network_timeout=60#theheartbeati......
  • DFS(深度优先搜索)
    DFS(深度优先搜索)顾名思义,深度优先搜索,即搜索的一种;在搜索时,优先向下一深度搜索,可以称作回溯法。主要实现方法是依靠递归函数;样例若使用DFS的搜索方法;在下图树各点中的遍历方法为:0->1->3->5->3->6->3->1->4->7->9->7->4->1->0......
  • hdu 5113 Black And White(DFS染色)
    Problem-5113(hdu.edu.cn)hdu没法提交,我以为我账号又崩了...#include<iostream>#include<cstring>usingnamespacestd;intT,n,m,k,kase;intcolor[30],ans[10][10];boolDFS(intx,inty,intcur){if(x>n)returntrue;for(inti=1;i<=k;i++){......
  • hdu 1175 连连看(DFS+剪枝)
    Problem-1175(hdu.edu.cn)根据转弯次数和有没有找到答案来剪枝#include<iostream>#include<cstring>usingnamespacestd;constintN=1010;intn,m,q,x1,y1,x2,y2,flag;intv[N][N],map[N][N];intdirection[4][2]={{1,0},{-1,0},{0,1},{0,-1}};#definecheck(x,y)......
  • poj 2676 Sudoku(DFS+回溯+剪枝)
    2676--Sudoku(poj.org)#include<iostream>#include<cstring>usingnamespacestd;intt,row[10][10],col[10][10],grid[10][10],map[10][10];boolDFS(intr,intc){if(r==10)returntrue;boolflag=false;if(map[r][c]){if(c=......
  • 【算法】DFS
    DFSDFS是一种遍历或搜索图、树或图像等数据结构的算法,当然这个图、树未必存储下来。常见的是通过某种关系构造出的搜索树,搜索树一般是排列型搜索树和子集型搜索树。DFS一般使用栈或递归。一道模板题#include<bits/stdc++.h>usingnamespacestd;constintN=50;intn,m......
  • DFS基础与回溯
    回溯法简介回溯法一般使用DFS(深度优先搜索(递归))实现,DFS是一种遍历或搜索图,树或图像等数据结构的算法。上述数据结构不保存下来就是回溯法。常见的是搜索树,排列型搜索树(节点数一般为n!)与子集型搜索树(节点数一般为2n)。DFS从起始点开始,沿着一条路尽可能深入,直到无法继续回溯到上......