当前位置: 首页 > article >正文

【蓝桥杯】:蓝桥杯之路径之谜

在这里插入图片描述
在这里插入图片描述

  1. 题目分析
    • 这是一道路径谜题,描述了一个骑士在一个(n\times n)方格组成的城堡中行走的问题。
    • 骑士从西北角(入口)走到东南角(出口),可以横向或纵向移动,但不能斜着走,也不能跳跃。
    • 每走到一个新方格,要向正北方和正西方各射一箭,城堡的西墙和北墙各有(n)个靶子。
    • 同一个方格只允许经过一次,题目要求根据靶子上箭的数目推断骑士的行走路线。
  2. 解题思路
    • 可以使用深度优先搜索(DFS)来解决这个问题。
    • 从入口开始,尝试向四个方向(东、南、西、北)移动,每次移动到一个新方格时,检查是否满足条件(不能斜着走,不能跳跃,同一个方格只允许经过一次)。
    • 每移动到一个新方格,记录下对靶子的影响(正北方和正西方的靶子箭数加1)。
    • 如果移动到的方格是出口,且靶子上的箭数与题目给出的一致,则找到了一条可行的路径。
    • 如果在某一步无法继续移动(所有方向都不符合条件),则需要回溯到上一步,尝试其他方向。
  3. 深度优先遍历(DFS)思想
    • 基本概念
      • 深度优先遍历是一种图(或树)的遍历算法。它从起始节点开始,沿着一条路径尽可能深地探索下去,直到无法继续或达到目标,然后回溯到上一个未完全探索的节点,继续探索其他路径。
    • 实现方式
      • 通常使用递归或栈来实现。在递归实现中,函数会不断调用自身来深入探索图的节点,直到达到终止条件。在栈实现中,将节点压入栈中,每次从栈顶取出节点进行探索。
    • 应用场景
      • 常用于寻找图中的路径、连通分量、拓扑排序等问题。在本题中,用于寻找骑士在城堡中的可行路径。
  4. 回溯思想
    • 基本概念
      • 回溯是一种在搜索过程中进行剪枝的技术。当发现当前路径不可能达到目标时,回退到上一个状态,尝试其他可能的路径。
    • 实现方式
      • 在搜索算法中,当遇到不满足条件的情况时,撤销当前操作,返回到上一步操作的状态,然后尝试其他选择。
    • 应用场景
      • 常用于解决组合优化问题、迷宫问题、数独问题等。在本题中,当骑士走到一个无法继续前进的方格时,需要回溯到上一个方格,尝试其他方向的移动。

通过以上思路和算法思想,可以尝试编写代码来解决这道路径谜题。

#include<iostream>
#include<vector>
//#include<bits/stdc++.h>
int n, a[25], b[25], k1, k2;
//定义一个二维数组标记上下左右;
const int v[4][2] = { 0, 1, 0, -1, 1, 0, -1, 0 };
int dx[4] = { 0,0,1,-1 };
int dy[4] = { 1,-1,0,0 };
//int flag;//标记默认为0;
int flag;
int vis[25][25], num, s[600];
using namespace std;
//实现我们的dfs;
void dfs(int x, int y, int k)
{
    //判断边界情况1;
    if (x < 1 || y < 1 || x > n || y > n)
    {
        return;
    }
    //判断边界情况2;b[x]表示行数没有走过;a[y]表示列数没有没走过;
    //if (b[x] < 0 || a[y] || flag == 1)
    //{
    //    return;
    //}

    if (b[x] < 0 || a[y] < 0 || flag == 1)//防止我们误判当前没有越过起点;
    {
        return;
    }
    //成功的情况下;
    s[k] = (x - 1) * n + (y - 1);
    //找到答案就返回;
    if (x == n && y == n && k1 == 1 && k2 == 1)
    {
        //正难则反;从终点倒推到起点的(k1==1&&k2==1)的位置;
        //不要去想展开图 我们相信我们走到这一步已经完成了我们的走到终点的目的;
        flag = 1;
        num = k;//num变量存储我们的k步;
        return;
    }
    for (int i = 0; i < 4; i++)
    {
        int xx = x + dx[i], yy = y + dy[i];//上下左右遍历矩阵;
        if (vis[xx][yy])
            //如果这个点已经走过了则跳过当前点;
        {
            continue;//如果这个点遍历过则跳过该点(题目要求);
        }
        b[xx]--;
        a[yy]--;
        k1--;
        k2--;
        vis[xx][yy] = 1;//标记此点已经被遍历过了;
        dfs(xx, yy, k + 1);//从下一个点继续遍历;
        //恢复现场;
        b[xx]++;
        a[yy]++;
        k1++;
        k2++;
        vis[xx][yy] = 0;//标记为false重新遍历;
    }
}
//void dfs(int x, int y, int k)    //常规dfs搜索模板;
//{
//    if (x < 1 || y < 1 || x > n || y > n) return;    //判断越界;
//    //if (b[x] < 0 || a[y] < 0 || flag == 1) return;    //不符合题意或找到答案了就返回;
//    //坐标索引公式:假设矩阵的大小是 n* m 那么对于位置(x, y) 其在一维数组中的索引可以通过公式 index = x * m + y 来计算;
//    s[k] = (x - 1) * n + (y - 1);      //记录路径,(编号可用坐标表示为i*m+j,m为列数);
//    if (x == n && y == n && k1 == 1 && k2 == 1)    //找到答案就返回;
//    {
//        num = k;
//        return;
//        //不要去想展开图 我们相信我们走到这一步已经完成了我们的走到终点的目的;
//    }
//    for (int i = 0; i < 4; i++)    //查找右左下上;
//    {
//        int xx = x + v[i][0];
//        int yy = y + v[i][1];
//        if (vis[xx][yy] == 1) continue;    //该点走过,跳过;
//        b[xx]--;
//        a[yy]--;
//        k1--;
//        k2--;
//        vis[xx][yy] = 1;
//        dfs(xx, yy, k + 1);
//        b[xx]++;                      //回溯,还原值;
//        a[yy]++;
//        k1++;
//        k2++;
//        vis[xx][yy] = 0;
//    }
//}
int main()
{
    cin >> n;
    for (int i = 1; i <= n; i++)
    {
        cin >> a[i];
        k1 += a[i];//记录每列要走的总数;
    }
    for (int i = 1; i <= n; i++)
    {
        cin >> b[i];
        k2 += b[i];;
    }
    flag = 0;
    vis[1][1] = 1;//第一个位置的坐标为true;
    dfs(1, 1, 1);//dfs深度优先遍历从第一个坐标开始遍历;
    for (int i = 1; i <= num; i++)
    {
        cout << s[i] << " ";
    }
    return 0;
}

http://www.kler.cn/a/463070.html

相关文章:

  • 二、CSS基础
  • 【从零开始入门unity游戏开发之——unity篇05】unity6基础入门——运行游戏按钮、Game游戏窗口和Project项目窗口介绍
  • lec5-传输层原理与技术
  • Flash Attention V3使用
  • AngularJS 过滤器:提升用户体验的数据处理利器
  • 运算符重载 - 自定义运算符行为
  • 机器人C++开源库The Robotics Library (RL)使用手册(四)
  • 关于ElasticSearch
  • 搭建医疗产品行业知识中台的手册
  • 深度学习在文本情感分析中的应用
  • 基于Redis的分布式锁
  • easybox
  • 【YashanDB知识库】hive初始化崖山报错YAS-04209
  • 万里数据库GreatSQL监控解析
  • 永嘉县瓯北六小:庆元旦,献爱心,让新永嘉人在童装节中找到归属感!
  • Golang学习历程【第五篇 复合数据类型:数组切片】
  • ShardingSphere-Proxy分表场景测试案例
  • CPT203 Software Engineering 软件工程 Pt.4 软件设计(中英双语)
  • Spring 核心技术解析【纯干货版】- II:Spring 基础模块 Spring-Beans 模块精讲
  • pyside6总结
  • 网络编程原理:回显服务器与客户端通信交互功能
  • Day20:逻辑运算
  • 30.Marshal.AllocHGlobal C#例子
  • 递归算法.
  • AI对接之JSON Output
  • 使用连字符容易出错,尽量使用驼峰式的