迷宫 蓝桥杯

问题描述

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

迷宫为一个 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;
} 
相关推荐
cpp_250117 分钟前
P10098 [ROIR 2023] 地铁建设 (Day 2)
数据结构·c++·算法·贪心·二分答案·洛谷题解
阳明山水1 小时前
TimesFM与Moirai MoE零样本预测解析
人工智能·深度学习·算法·机器学习·架构
铅笔侠_小龙虾1 小时前
Rust 学习(2)-变量、常量与 shadowing
学习·算法·rust
AI科技星1 小时前
基于全域数学公理体系的三元极值题最简求解法【乖乖数学】
线性代数·算法·游戏·决策树·机器学习·乖乖数学·全域数学
大鱼>2 小时前
宠物异常行为预警系统:边缘计算与实时检测
人工智能·深度学习·算法·iot·宠物
apcipot_rain3 小时前
某双非机试真题
算法
米尔的可达鸭3 小时前
深入操作系统 Socket 底层:套接字控制块、FD映射、阻塞IO核心完整实现
arm开发·数据结构·websocket·网络协议·算法·架构·安全架构
tachibana24 小时前
hot100 课程表(207)
java·数据结构·算法·leetcode
神仙别闹4 小时前
编写基于C++ Huffman 算法的无损压缩程序和解压程序
java·c++·算法
大鱼>4 小时前
宠物活动轨迹追踪系统:GPS/BDS+UWB+BLE多定位融合方案
人工智能·深度学习·算法·iot·宠物