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

2023-3-2 刷题情况

迷宫

题目描述

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

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

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

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

输出描述

输入共 1+m 行, 第一行为两个正整数 n,m 。后面 m 行, 每行四个正整数 , x i 1 , y i 1 , x i 2 , y i 2 x_{i1},y_{i1},x_{i2},y_{i2} xi1,yi1,xi2,yi2表示第 i 个传送门连接的两个格 子坐标。

输出描述

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

样例

样例输入

2 1
1 1 2 2

样例输出

0.75

样例解释

计算的是一个期望值,是矩阵中所有节点的最短路到终点的总和/ 矩阵大小。

思路

边权为1,还是可以使用bfs,不过由于传送门的存在,需要进行特殊判断。

代码实现

import java.util.*;

public class Main{
	
	public static class pair{
		int first;
		int second;
		
		public pair(int first, int second) {
			this.first = first;
			this.second = second;
		}
	}
	
	static int[][] dir = {{1, 0},{-1, 0},{0, 1},{0, -1}};
	
	public static void main(String[] args) {
		Scanner sc = new Scanner(System.in);
		int n = sc.nextInt(), m = sc.nextInt();
		int[][] matrix = new int[n + 1][n + 1];
		boolean[][] vis = new boolean[n + 1][n + 1];
		List<pair> list[][] = new ArrayList[n + 1][n + 1];
		for(int i = 0; i < m; i++) {
			int a = sc.nextInt(), b = sc.nextInt(), c = sc.nextInt(), d = sc.nextInt();
			if(list[a][b] == null) list[a][b] = new ArrayList<>();
			if(list[c][d] == null) list[c][d] = new ArrayList<>();
			list[a][b].add(new pair(c, d));
			list[c][d].add(new pair(a, b));
		}
		matrix[n][n] = 0;
		vis[n][n] = true; 
		Queue<pair> queue = new ArrayDeque<>();
		queue.offer(new pair(n, n));
		while(!queue.isEmpty()) {
			pair cur = queue.poll();
			if(list[cur.first][cur.second] != null) {
				for(pair c : list[cur.first][cur.second]) {
					if(!vis[c.first][c.second]) {
						vis[c.first][c.second] = true;
						matrix[c.first][c.second] = matrix[cur.first][cur.second] + 1;
						queue.offer(c);
					}
				}
			}
			for(int[] d : dir) {
				int x = cur.first + d[0];
				int y = cur.second + d[1];
				if(0 < x && x <= n && 0 < y && y <= n && !vis[x][y]) {
					vis[x][y]= true; 
					matrix[x][y] = matrix[cur.first][cur.second] + 1; 
					queue.offer(new pair(x, y));
				}
			}
			
		}
		long sum = 0;
		for(int[] r : matrix) {
			for(int c : r)
				sum += c;
		}
		System.out.printf("%.2f", (double)((sum * 1.0)  / (n * n)));
		sc.close();
	}
}

相关文章:

  • 【数据结构】八大经典排序总结
  • 嵌入式学习笔记——基于Cortex-M的单片机介绍
  • 把数组里面数值排成最小的数
  • CEC2017:斑马优化算法(Zebra Optimization Algorithm,ZOA)求解cec2017(提供MATLAB代码)
  • Java并发简介(什么是并发)
  • 【uniapp】getOpenerEventChannel().once 接收参数无效的解决方案
  • 【蓝桥杯集训·每日一题】Acwing 3729. 改变数组元素
  • 集成电路相关书籍
  • 【项目】Vue3+TS CMS 基本搭建相关配置
  • KDHX-8700无线高压核相相序表
  • AMD发布23.2.1 新驱动 支持开年新作《魔咒之地》
  • JVM类加载机制
  • ACM第一周---周训---题目合集.
  • Java网络编程之UDP和TCP套接字
  • 最最普通程序员,如何利用工资攒够彩礼,成为人生赢家
  • 345-反转字符串中的元音字母
  • Angular 响应式表单之下拉框
  • conda常用的命令
  • Git的一些常用操作
  • IndexedDB
  • java8-模拟hadoop
  • JavaScript学习总结——原型
  • vue学习系列(二)vue-cli
  • windows下使用nginx调试简介
  • 对象引论
  • 计算机常识 - 收藏集 - 掘金
  • 理解 C# 泛型接口中的协变与逆变(抗变)
  • 聊聊flink的TableFactory
  • 前端面试之CSS3新特性
  • 前端设计模式
  • 浅析微信支付:申请退款、退款回调接口、查询退款
  • 首页查询功能的一次实现过程
  • 无服务器化是企业 IT 架构的未来吗?
  • 一个6年java程序员的工作感悟,写给还在迷茫的你
  • 翻译 | The Principles of OOD 面向对象设计原则
  • ​Kaggle X光肺炎检测比赛第二名方案解析 | CVPR 2020 Workshop
  • ​secrets --- 生成管理密码的安全随机数​
  • #WEB前端(HTML属性)
  • #我与Java虚拟机的故事#连载11: JVM学习之路
  • $NOIp2018$劝退记
  • (1)Map集合 (2)异常机制 (3)File类 (4)I/O流
  • (2.2w字)前端单元测试之Jest详解篇
  • (3)(3.2) MAVLink2数据包签名(安全)
  • (NO.00004)iOS实现打砖块游戏(九):游戏中小球与反弹棒的碰撞
  • (翻译)Entity Framework技巧系列之七 - Tip 26 – 28
  • (附源码)python房屋租赁管理系统 毕业设计 745613
  • (附源码)计算机毕业设计大学生兼职系统
  • (十六)一篇文章学会Java的常用API
  • (转)c++ std::pair 与 std::make
  • (转)EOS中账户、钱包和密钥的关系
  • (转载)Google Chrome调试JS
  • (转载)Linux 多线程条件变量同步
  • (轉貼) 蒼井そら挑戰筋肉擂台 (Misc)
  • (最完美)小米手机6X的Usb调试模式在哪里打开的流程
  • .bat批处理(九):替换带有等号=的字符串的子串