迷宫 蓝桥杯

问题描述

这天, 小明在玩迷宫游戏。

迷宫为一个 n×n 的网格图, 小明可以在格子中移动, 左上角为 (1,1), 右下角 (n, n)为终点。迷宫中除了可以向上下左右四个方向移动一格以外, 还有 m 个双向传送门可以使用, 传送门可以连接两个任意格子。

假如小明处在格子(x1​,y1​), 同时有一个传送门连接了格子(x1​,y1​) 和 (x2​,y2​), 那么小明既可以花费 1 的步数向上下左右四个方向之一走一格 (不能越过边界), 也可以花费 1 的步数通过传送门走到格子 (x2​,y2​) 去。

而对于同一个迷宫, 小明每次进入的初始格子是在这n×n 个格子中均匀随 机的 (当然运气好可以直接随机到终点), 他想知道从初始格子走到终点的最短 步数的期望值是多少。

输入格式

输入共 1+m 行, 第一行为两个正整数 n,m 。

后面 mm 行, 每行四个正整数 xi1​,yi1​,xi2​,yi2​ 表示第 i 个传送门连接的两个格子坐标。

输出格式

输出共一行, 一个浮点数表示答案 (请保留两位小数)。

样例输入

复制代码
2 1
1 1 2 2 

样例输出

复制代码
0.75

反向搜索 只要搜一次就行

另外本题不标记 因为传送门会使之前的结果不一定是最优的。增加了空间复杂度。

复制代码
#include<bits/stdc++.h>
using namespace std;
#define int long long 
#define fp(i,a,b) for(int i=a;i<=b;++i)
#define PII pair<int,int>
const int N=2e3+10;
const int mod=1e9+7;
const double eps=1e-5;
typedef double db;
int dx[]={0,0,1,-1};
int dy[]={1,-1,0,0};
int n,m;
int dist[N][N];
vector<PII>door[N][N];
bool is_door[N][N];
void bfs()
{    
    memset(dist,0x3f,sizeof dist);
    dist[n][n]=0;
    queue<PII>q;
    q.push({n,n});
    
    while(q.size())
    {
        auto t=q.front();
        q.pop();
        
        for(int p=0;p<4;p++)
        {
            int X=dx[p]+t.first,Y=dy[p]+t.second;
            if(X<1||X>n||Y<1||Y>n) continue;
            
            if(dist[X][Y]>dist[t.first][t.second]+1)
            {
                dist[X][Y]=dist[t.first][t.second]+1;
                q.push({X,Y});
            }
            if(is_door[t.first][t.second])//如果当前点可以使用传送门 
            {
                //因为是反向搜图,可以多对一
                for(auto s:door[t.first][t.second])
                {
                    //取出里面的点
                    if(dist[s.first][s.second]>dist[t.first][t.second]+1)
                    {
                        dist[s.first][s.second]=dist[t.first][t.second]+1;
                        q.push({s.first,s.second});
                    } 
                } 
            }
            
        }
    } 
} 
signed main()
{
   cin>>n>>m;
   
   for(int i=1;i<=m;i++)
   {
   	  int a,b,c,d;
   	  cin>>a>>b>>c>>d;
   	  door[a][b].push_back({c,d});
      door[c][d].push_back({a,b});
      is_door[a][b]=is_door[c][d]=true;
   }
   bfs();
   int sum=0;
   for(int i=1;i<=n;i++)
   {
   	  for(int j=1;j<=n;j++)
   	  {
   	     sum+=dist[i][j];	
	  }
   }
   cout<<fixed<<setprecision(2)<<1.0*sum/(n*n)<<"\n";
    
	return 0;
} 
相关推荐
大明者省5 小时前
WSL2 Ubuntu22.04 GPU训练环境配置指南
人工智能·算法·计算机视觉
白狐_7986 小时前
408数据结构第8章:排序②——性质对比秒杀、场景选择与外部排序
java·数据结构·算法
zander2587 小时前
LeetCode 84:柱状图中的最大矩形——单调栈如何确定左右边界
java·数据结构·算法
Shell运维手记7 小时前
Linux 常用基础命令学习笔记
linux·运维·笔记·学习·算法·github
杨航 AI7 小时前
O(n log n):线性对数原理拆解 这个是排序算法的黄金复杂度之一。
算法·排序算法
船厂电气自动化ai大模型8 小时前
AI大模型与数学 第32课 函数凹凸性与二阶导数:拐点求解、凹凸区间计算(10道二阶导数计算题)
数据结构·人工智能·python·深度学习·算法
旖旎夜光8 小时前
LeetCode 3:无重复字符的最长子串(滑动窗口) —— 题解
数据结构·c++·算法·leetcode·滑动窗口
叠层归一研究院9 小时前
AGI 系统(十一):二阶网络 — 二阶递归 × 多主体 (元符号网络)
开发语言·人工智能·算法·php·agi
zlinear数据采集卡10 小时前
D223的PWM电机控制:6路独立脉冲+加减速算法深度解析
arm开发·stm32·嵌入式硬件·算法·fpga开发·架构
杨石兴10 小时前
31、玩具MoM:用2x2矩阵串起全套流程
人工智能·算法·矩阵·电磁学