迷宫 蓝桥杯

问题描述

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

迷宫为一个 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;
} 
相关推荐
Σίσυφος1900几秒前
线性与非线性 、齐次非齐次
算法
(❁´◡`❁)Jimmy(❁´◡`❁)12 分钟前
4815. 【NOIP2016提高A组五校联考4】ksum
算法
无限码力40 分钟前
科大讯飞秋招笔试真题 - 字符拼接 & 字典序最小的字符串拼接 & 圆心覆盖
算法·秋招·科大讯飞·科大讯飞笔试真题
Lips61143 分钟前
第四章 决策树
算法·决策树·机器学习
YuTaoShao1 小时前
【LeetCode 每日一题】2053. 数组中第 K 个独一无二的字符串
算法·leetcode·职场和发展
朔北之忘 Clancy2 小时前
第二章 分支结构程序设计(3)
c++·算法·青少年编程·竞赛·教材·考级·讲义
想逃离铁厂的老铁2 小时前
Day42 >> 188、买卖股票的最佳时机IV + 309.最佳买卖股票时机含冷冻期 + 714.买卖股票的最佳时机含手续费
算法·leetcode·职场和发展
wu_asia2 小时前
方阵对角线元素乘积计算
数据结构·算法
想逃离铁厂的老铁2 小时前
Day43 >> 300.最长递增子序列 + 674. 最长连续递增序列+ 718. 最长重复子数组
数据结构·算法
Yzzz-F2 小时前
P6648 [CCC 2019] Triangle: The Data Structure [st表]
算法