Toyota Programming Contest 2023#4(AtCoder Beginner Contest 311)D题题解

文章目录

  • [Grid Ice Floor](https://atcoder.jp/contests/abc311/tasks/abc311_d)
    • 问题建模
    • 问题分析
      • 1.分析移动时前后两个点之间的联系
      • 2.方法1通过BFS将所有按照给定运动方式可以到达的点都标记
        • 代码
      • 3.方法2采用DFS来标记路径上的点的运动状态
        • 代码

Grid Ice Floor

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

问题建模

给定一个n*m的字符矩阵有’.‘和’#‘两种字符,其中’.'为冰块是可移动的到的地方,‘#'为岩石无法移动到该地方。从点(2,2)出发,出发时选择一个方向移动,持续移动至撞上岩石时停止,并重新选择移动方向。问由点(2,2)出发最多可以经过的冰块数量为多少。

问题分析

1.分析移动时前后两个点之间的联系

若前一个点是由停止后,选择新的移动方向进行移动,则后一个点为保持前一个点的移动方向进行移动。若前一个点是移动的,则到后一个点既有可能保持与前一个点同样的移动方向继续移动,也有可能是无法移动从而停止。通过分析两点间的联系,可以发现每个点的状态有2大类,一类为停止,一类为运动,运动里有按运动方向分为上下左右四种。

2.方法1通过BFS将所有按照给定运动方式可以到达的点都标记

因为任意一个点只要有一种运动状态被标记,则该点一定可以由(2,2)点到达,那我们可以让(2,2)为起点跑BFS将所有可以可到达路径上的点都标记,最终统计所有被标记过的点即可得到答案。

代码

#include<bits/stdc++.h>#define x first
#define y second
#define C(i) str[0][i]!=str[1][i]
using namespace std;
typedef unsigned long long ULL;
typedef long long LL;
typedef pair<int, int> PII;
typedef pair<LL, LL> PLL;
const int N =210, Mod =998244353;
int n,m;
string g[N];
bool st[N][N][5];///记录该点的5种状态
int dx[4]={-1,0,1,0};
int dy[4]={0,1,0,-1};void  bfs(){memset(st,false,sizeof(st));st[1][1][4]=true;queue<int> q;///将坐标信息和状态映射为一个整数并出入队列中q.push(5*(m+1)+4);while(q.size()){int qt=q.front();q.pop();int x=(qt/5)/m;int y=(qt/5)%m;int d=qt%5;if(d==4){///若当前状态为停止,则选择新的方向移动for(int i=0;i<4;i++){int nx=x+dx[i],ny=y+dy[i];if(nx>0&&nx<n-1&&ny>0&&ny<m-1&&g[nx][ny]!='#'&&!st[nx][ny][i]){st[nx][ny][i]=true;q.push(5*(m*nx+ny)+i);}}}else {int nx=x+dx[d],ny=y+dy[d];///若当前运动方向可以接着移动,则继续移动,否则停止,并选择新的方向if(nx>0&&nx<n-1&&ny>0&&ny<m-1&&g[nx][ny]!='#'&&!st[nx][ny][d]){st[nx][ny][d]=true;q.push(5*(m*nx+ny)+d);}else {if(!st[x][y][4]){st[x][y][4]=true;q.push(5*(m*x+y)+4);}}}}
}void solve() {cin >>n >>m;for(int i=0;i<n;i++)    cin >>g[i];bfs();int cnt=0;for(int i=0;i<n;i++){for(int j=0;j<m;j++){///若该点有一种状态被标记,则该点可达cnt+=(st[i][j][0]|st[i][j][1]|st[i][j][2]|st[i][j][3]|st[i][j][4]);}}cout <<cnt<<endl;
}  int main() {int t = 1;//cin >> t;while (t--) solve();return 0;
}

3.方法2采用DFS来标记路径上的点的运动状态

代码

停止后再选择新的移动方向可以不用设置为一个单独的状态,而是直接选择新的方向,从而省去停止状态

#include<bits/stdc++.h>#define x first
#define y second
#define C(i) str[0][i]!=str[1][i]
using namespace std;
typedef unsigned long long ULL;
typedef long long LL;
typedef pair<int, int> PII;
typedef pair<LL, LL> PLL;
const int N =210, Mod =998244353;
int n,m;
string g[N];
bool st[N][N][4];
int dx[4]={-1,0,1,0};
int dy[4]={0,1,0,-1};void dfs(int x,int y,int d){if(g[x][y]=='#'||st[x][y][d])    return ;st[x][y][d]=true;int nx=x+dx[d],ny=y+dy[d];if(g[nx][ny]!='#'){///可以继续移动dfs(nx,ny,d);}else{//更换方向for(int i=0;i<4;i++){nx=x+dx[i],ny=y+dy[i];dfs(nx,ny,i);}}
}void solve() {cin >>n >>m;for(int i=0;i<n;i++)    cin >>g[i];memset(st,false,sizeof(st));dfs(1,1,3);int cnt=0;for(int i=0;i<n;i++){for(int j=0;j<m;j++){cnt+=(st[i][j][0]|st[i][j][1]|st[i][j][2]|st[i][j][3]);}}cout <<cnt<<endl;
}  int main() {int t = 1;//cin >> t;while (t--) solve();return 0;
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.hqwc.cn/news/53235.html

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

高并发负载均衡---LVS

目录 前言 一&#xff1a;负载均衡概述 二&#xff1a;为啥负载均衡服务器这么快呢&#xff1f; ​编辑 2.1 七层应用程序慢的原因 2.2 四层负载均衡器LVS快的原因 三&#xff1a;LVS负载均衡器的三种模式 3.1 NAT模式 3.1.1 什么是NAT模式 3.1.2 NAT模式实现LVS的缺点…

springboot+vue网红酒店客房预定系统的设计与实现_ui9bt

随着计算机技术发展&#xff0c;计算机系统的应用已延伸到社会的各个领域&#xff0c;大量基于网络的广泛应用给生活带来了十分的便利。所以把网红酒店预定管理与现在网络相结合&#xff0c;利用计算机搭建网红酒店预定系统&#xff0c;实现网红酒店预定的信息化。则对于进一步…

供水管网漏损监测,24小时保障城市供水安全

供水管网作为城市生命线重要组成部分&#xff0c;其安全运行是城市建设和人民生活的基本保障。随着我国社会经济的快速发展和城市化进程的加快&#xff0c;城市供水管网的建设规模日益增长。然而&#xff0c;由于管网老化、外力破坏和不当维护等因素导致的供水管网漏损&#xf…

电脑连接KONICA MINOLTA(柯尼卡美能达) 打印机及驱动安装

电脑系统&#xff1a;Windows 7 安装的打印机型号&#xff1a;Konica minolta bizhub 363 驱动下载&#xff1a;https://www.konicaminolta.com.cn/support/drivers/index.html 打印机配置好网络 1.打开控制面板&#xff0c;或点击桌面开始&#xff08;WIN&#xff09;&#x…

Webpack5新手入门简单配置

1.初始化项目 yarn init -y 2.安装依赖 yarn add -D webpack5.75.0 webpack-cli5.0.0 3.新建index.js 说明&#xff1a;写入下面的一句话 console.log("hello webpack"); 4.执行命令 说明&#xff1a;如果没有安装webpack脚手架就不能执行yarn webpack&#xff08…

47.Linux学习day01 基础命令详解1(很全面)

目录 一、Linux和Windows的区别 二、Linux系统目录结构 常见目录说明 三、Linux常见的基础命令 1.pwd 2.cd 3.ls 4.man 5. touch 6.mkdir 7. rmdir 今天正式学习了linux的一些基础操作和基础知识&#xff0c;以及linux和windows的区别。 一、Linux和Windows的区…

Your local changes to the following files would be overwritten by checkout

Git 之 Your local changes to the following files would be overwritten by checkout 今天在切换分支时遇到了这样一个问题&#xff1a; 首先翻译下&#xff1a; Your local changes to the following files would be overwritten by checkout 大致意思就是&#xff1a; 当…

HCIP---OSPF的MGRE实验

一、实验要求&#xff1a; 1、R6为ISP只能配置ip地址&#xff0c;R1-5的环回为私有网段 2、R1/4/5为全连的MGRE结构&#xff0c;R1/2/3为星型的拓扑结构&#xff0c;R1为中心站点 3、所有私有网段可以互相通讯&#xff0c;私有网段使用OSPF协议完成 二、实验步骤 &#xf…

Leetcode-每日一题【剑指 Offer 09. 用两个栈实现队列】

题目 用两个栈实现一个队列。队列的声明如下&#xff0c;请实现它的两个函数 appendTail 和 deleteHead &#xff0c;分别完成在队列尾部插入整数和在队列头部删除整数的功能。(若队列中没有元素&#xff0c;deleteHead 操作返回 -1 ) 示例 1&#xff1a; 输入&#xff1a; [&…

数据库的约束 详解

一、约束的概述 1.概念:约束是作用于表中字段上的规则&#xff0c;用于限制存储在表中的数据。 2&#xff0e;目的:保证数据库中数据的正确、有效性和完整性。 3.分类: 约束描述关键字非空约束限制该字段的数据不能为nullNOT NULL唯一约束保证该字段的所有数据都是唯一、不…

c51单片机16个按键密码锁源代码(富proteus电路图)

注意了&#xff1a;这个代码你是没法直接运行的&#xff0c;但是如果你看得懂&#xff0c;随便改一改不超过1分钟就可以用 #include "reg51.h" #include "myheader.h" void displayNumber(unsigned char num) {if(num1){P10XFF;P10P11P14P15P160;}else if…

【MySQL】事务与隔离级别

目录 一、事务的概念二、为什么要有事务三、引擎对事务的支持四、事务的提交方式五、事务的操作5.1 准备5.2 正常事务操作5.3 非正常事务5.4 总结 六、事务的隔离级别6.1 隔离性6.2 隔离级别6.3 隔离级别的查看6.4 设置隔离级别6.4.1 会话级别6.4.2 全局级别 6.5 隔离级别的具体…