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

UVA-1601 万圣节后的早晨 题解答案代码 算法竞赛入门经典第二版

GitHub - jzplp/aoapc-UVA-Answer: 算法竞赛入门经典 例题和习题答案 刘汝佳 第二版

以三个点的当前位置作为状态,广度优先遍历,找到终点即为最短次数。

注意:

一次可以移动多个点,但是每个点只能移动一步。在同一次中,B可以移动到A离开前的位置上,即如果A走了,B可以去A之前的位置。因此,这三个点的移动和判断是有先后顺序的。对每个状态遍历时,情况实际上有 3的全排列(值为6),以及每个点移动的可能四种位置: 3! * 4^3。当然因为墙的存在,因此并没有这么多。

由于最高只有3,因此我的全排列写的不怎么优雅,直接嵌套循环完成了。注意每个点可以动,也可以不动,因此我们要考虑只有一个点动,两个点动的情况。写全排列时。如果第一个点动了大现已经遍历过,这时候不能放入队列(因为在其他点不动的情况下,这个状态已经遍历过了)。但是如果后面的点还继续动,那么这并不是一个完整的状态,因此不应该终止全排列。

按照上面的方法做的话,耗时很久,我扣了点细节,最后终于压线AC。(时间限制12000ms)

1. 根据题目描述,很多节点周围都是墙,因此用邻接表效率更高一些。

2. 一个点的坐标位置为1-16, x和y很容易放到一个数字中存储的。相对于每次计算x1 == x2 && y1 == y2, 一个数字的计算次数更少。其实三个结点的xy位置应该可以整合为一个数字的,这样效率会更高。 

3. 我的答案中用到了struct,一些辅助的判断函数,使用引用而不是直接将整个对象值作为参数,性能会提高一些。

#include <stdio.h>
#include <string.h>
#include <queue>
#include <vector>using namespace std;int graph[20][20];
vector<int> graphVec[300];
int w, h, n;struct Point {char ch;int pos;
};
Point initPoints[3];
Point suppPoints[3];struct Status {int pos[3];int step;
};
Status origin, terminal;bool access[300][300][300];int steps[4][2] = { {1, 0}, {-1, 0}, {0, 1}, {0, -1} };bool sameLetter(char small, char big) {return small == big - 'A' + 'a';
}
bool statusEqual(Status &s1, Status &s2) {for (int i = 0; i < n; ++i) {if (s1.pos[i] != s2.pos[i]) return false;}return true;
}int xy2Num(int x, int y) {return x * 17 + y;
}void num2XY(int num, int *x, int *y) {*x = num / 17;*y = num % 17;
}bool judgeAcc(Status &s) {if (n == 1) return access[s.pos[0]][0][0];if (n == 2) return access[s.pos[0]][s.pos[1]][0];if (n == 3) return access[s.pos[0]][s.pos[1]][s.pos[2]];
}void setAcc(Status &s) {if (n == 1) access[s.pos[0]][0][0] = true;if (n == 2) access[s.pos[0]][s.pos[1]][0] = true;if (n == 3) access[s.pos[0]][s.pos[1]][s.pos[2]] = true;
}void printStatus(Status &s) {int x, y;for (int i = 0; i < n; ++i) {num2XY(s.pos[i], &x, &y);printf("[%d %d] ", x, y);}printf(" %d\n", s.step);
}void printGraphVec() {int i, j, x, y;for(i = 0; i < 300; ++i) {if(graphVec[i].size()) {num2XY(i, &x, &y);printf("%d %d - ", x, y);for(j = 0; j < graphVec[i].size(); ++j) {num2XY(graphVec[i][j], &x, &y);printf("[%d %d] ", x, y);}putchar('\n');}}putchar('\n');
}void init() {int i, j, k, initLen = 0, suppLen = 0;int x, y;memset(access, 0, sizeof(access));for(i = 0; i < 300; ++i) {graphVec[i].clear();}for (i = 1; i <= h; ++i) {while (getchar() != '\n') ;for (j = 1; j <= w; ++j)  {graph[i][j] = getchar();if (graph[i][j] >= 'a' && graph[i][j] <= 'z')initPoints[initLen++] = {char(graph[i][j]), xy2Num(i, j)};if (graph[i][j] >= 'A' && graph[i][j] <= 'Z')suppPoints[suppLen++] = {char(graph[i][j]), xy2Num(i, j)};}}for(i = 2; i < h; ++i) {for (j = 2; j < w; ++j)  {if(graph[i][j] == '#') continue;for(k = 0; k < 4; ++k) {x = i + steps[k][0];y = j + steps[k][1];if(graph[x][y] == '#') continue;graphVec[xy2Num(i, j)].push_back(xy2Num(x, y));}}}// printGraphVec();for (i = 0; i < n; ++i) {origin.pos[i] = initPoints[i].pos;for (j = 0; j < n; ++j) {if (sameLetter(initPoints[i].ch, suppPoints[j].ch)) {terminal.pos[i] = suppPoints[j].pos;break;}}}origin.step = 0;terminal.step = 0;setAcc(origin);// printStatus(origin);// printStatus(terminal);
}bool judgePos(Status &s) {int i, j;for (i = 0; i < n; ++i) {for (j = 0; j < n; ++j) {if (i == j) continue;if (s.pos[i] == s.pos[j]) return false;}}return true;
}int compute() {int i, j, k, a1, a2, a3;int num1, num2, num3, len1, len2, len3;queue<Status> qu;Status s0, s1, s2, s3;qu.push(origin);while (!qu.empty()) {s0 = qu.front();qu.pop();// putchar('\n');// printStatus(s0);s0.step++;for (i = 0; i < n; ++i) {num1 = s0.pos[i]; len1 = graphVec[num1].size();for (a1 = 0; a1 < len1; ++a1) {s1 = s0;s1.pos[i] = graphVec[num1][a1];if (!judgePos(s1)) continue;if (!judgeAcc(s1)) {// printStatus(s1);setAcc(s1); qu.push(s1);}if (statusEqual(s1, terminal)) return s1.step;for (j = 0; j < n; ++j) {if (i == j) continue;num2 = s1.pos[j]; len2 = graphVec[num2].size();for (a2 = 0; a2 < len2; ++a2) {s2 = s1;s2.pos[j] = graphVec[num2][a2];if (!judgePos(s2)) continue;if (!judgeAcc(s2)) {// printStatus(s2);setAcc(s2); qu.push(s2);}if (statusEqual(s2, terminal)) return s2.step;for (k = 0; k < n; ++k) {if (k == i || k == j) continue;num3 = s2.pos[k]; len3 = graphVec[num3].size();for (a3 = 0; a3 < len3; ++a3) {s3 = s2;s3.pos[k] = graphVec[num3][a3];if (!judgePos(s3)) continue;if (!judgeAcc(s3)) {// printStatus(s3);setAcc(s3); qu.push(s3);}if (statusEqual(s3, terminal)) return s3.step;}}}}}}}
}int main() {while (scanf("%d %d %d", &w, &h, &n) == 3 && w != 0) {init();printf("%d\n", compute());}return 0;
}

相关文章:

UVA-1601 万圣节后的早晨 题解答案代码 算法竞赛入门经典第二版

GitHub - jzplp/aoapc-UVA-Answer: 算法竞赛入门经典 例题和习题答案 刘汝佳 第二版 以三个点的当前位置作为状态&#xff0c;广度优先遍历&#xff0c;找到终点即为最短次数。 注意&#xff1a; 一次可以移动多个点&#xff0c;但是每个点只能移动一步。在同一次中&#xf…...

nacos 403错误

403错误 2023-08-12 18:04:55,418 [main] ERROR [com.alibaba.cloud.nacos.client.NacosPropertySourceBuilder:106] [trace,span,parent] - get data from Nacos error,dataId:gateway-server.yaml, com.alibaba.nacos.api.exception.NacosException: <html><body&…...

Python遥感图像处理应用篇(三十四):GDAL+Scikit-image+GLCM计算遥感图像纹理特征

1.运行环境 GDAL 3.4.2,Scikit-image最新版本0.19.3,numpy1.21.5 GDAL主要用于实现图像的读取和保存,Scikit-image和numpy对图像进行各种计算处理。 在调试好之前,由于numpy版本(1.16.6)低的问题,运行提示如下错误,更新为1.21.5版本之后就可以正常运行了,在此记录一…...

solr迁移到另一个solr中(docker单机)

背景介绍 solr数据迁移&#xff0c;或者版本升级&#xff0c;需要用到迁移&#xff0c;此处记录一下迁移方法以及过程中遇到的问题。我这边使用的是docker环境&#xff0c;非docker部署的应该也是一样的。 solr部署教程 准备工作 ● solrA 版本&#xff1a; 8.11.2 (已有so…...

谁能讲清楚Spark之Spark系统架构

### 整体架构概述 Spark与Hadoop MapReduce的结构类似,Spark也采用Master-Worker结构。如果一个Spark集群由4个节点组成,即1个Master节点和3个Worker节点,那么在部署Standalone版本后,Spark部署的系统架构图如图2.1所示。简单来说,Master节点负责管理应用和任务,…...

力扣:59. 螺旋矩阵 II(Python3)

题目&#xff1a; 给你一个正整数 n &#xff0c;生成一个包含 1 到 n2 所有元素&#xff0c;且元素按顺时针顺序螺旋排列的 n x n 正方形矩阵 matrix 。 来源&#xff1a;力扣&#xff08;LeetCode&#xff09; 链接&#xff1a;力扣&#xff08;LeetCode&#xff09;官网 - 全…...

【electron】electron项目创建的方式:

文章目录 【1】npm init quick-start/electron&#xff08;推荐&#xff09;【2】 克隆仓库&#xff0c;快速启动【3】 通过脚手架搭建项目【4】 手动创建项目 【Electron官网】https://www.electronjs.org/zh/docs/latest/api/app 【1】npm init quick-start/electron&#xf…...

Vim学习(一)——基本命令与三种模式

写在前面&#xff0c; 致敬 8月3日&#xff0c;Vim创始人Bram Moolenaar去世&#xff0c;在此向老爷子致敬&#xff01;感谢他为这个世界带来的优秀编辑器Vim。 基本介绍 Vim全称叫Vi IMproved. 而vi则是Visual Interface的缩写&#xff0c;他们处理都是ASCII码字符数据&am…...

unity新输入系统的简单使用(New InputSystem)

1、在包管理器 unity注册表中下载安装InputSystem 2、给玩家添加组件PlayerInput&#xff0c;点击CreatAction,创建一个InputAct InputAct,这是玩家的输入文件&#xff0c;在里面可以设置玩家输入 3、使用 例如玩家控制角色移动 在InputAct中&#xff0c;默认已经设置好了移…...

Redis——特性介绍与应用场景

Redis特性介绍 In-memory data structrues 众所周知&#xff0c;MySQL是一种关系型数据库&#xff0c;其通过表的结构存储数据&#xff0c;就类似于建立了一个excel表格来存储数据。但是像视频这类数据并不适合存储在关系型数据库中&#xff0c;因此存在非关系型数据库——通…...

网络:路由

1. 路由器 路由器工作在三层&#xff0c;每个接口都处于不用的网段中&#xff0c;即不同的广播域。但大多情况下&#xff0c;两台路由器直接相连的接口是同一个广播域&#xff0c;即一个网段。 路由器具有判断网络地址和选择路径的功能&#xff0c;能在多网络互联的环境中&…...

利用三维内容编辑器制作VR交互课件,简单好用易上手

随着虚拟现实技术的不断发展&#xff0c;越来越多的教育机构开始尝试将其应用于教育教学中。然而&#xff0c;要实现这一目标并不容易&#xff0c;需要专业的技术支持和开发团队。 为了解决这一问题&#xff0c;广州华锐互动研发了三维内容编辑器&#xff0c;它是一种基于虚拟现…...

中国首款量子计算机操作系统本源司南 PilotOS正式上线

中国安徽省量子计算工程研究中心近日宣布&#xff0c;中国国产量子计算机操作系统本源司南 PilotOS 客户端正式上线。 如果把量子芯片比喻成人的“心脏”&#xff0c;那么量子计算机操作系统就相当于人的“大脑”&#xff0c;量子计算应用软件则是人的“四肢”。 据安徽省量子…...

基层社会治理平台建设方案[113页PPT]

导读&#xff1a;原文《基层社会治理平台建设方案[113页PPT]》&#xff08;获取来源见文尾&#xff09;&#xff0c;本文精选其中精华及架构部分&#xff0c;逻辑清晰、内容完整&#xff0c;为快速形成售前方案提供参考。 完整版领取方式 完整版领取方式&#xff1a; 如需获取完…...

认识vite

一.了解vite的不同版本的更新 vite1版本是基于vue项目的&#xff0c;无法跨框架使用vite2可以跨框架&#xff08;vue2&#xff0c;vue3&#xff0c;react&#xff09;vite3模板变更&#xff1b;vite cli优化&#xff1b;import.meta.glob API变化&#xff1b;其他vite4主版本主…...

华为运动健康,十年创新天地宽

我听一位朋友讲过这样一个故事。某天早上&#xff0c;急诊科的医生迎来了一位患者&#xff0c;患者进来后直接说&#xff1a;“大夫&#xff0c;我房颤了。” 这位医生非常诧异&#xff0c;因为心脏房颤确实非常危急&#xff0c;但很多时候并没有明显的生理体征&#xff0c;患者…...

深度学习(37)—— 图神经网络GNN(2)

深度学习&#xff08;37&#xff09;—— 图神经网络GNN&#xff08;2&#xff09; 这一期主要是一些简单示例&#xff0c;针对不同的情况&#xff0c;使用的数据都是torch_geometric的内置数据集 文章目录 深度学习&#xff08;37&#xff09;—— 图神经网络GNN&#xff08…...

Unity游戏源码分享-乐节奏休闲游戏源码 guitar hero 支持mobile

Unity游戏源码分享-乐节奏休闲游戏源码 guitar hero 支持mobile 完整版下载地址&#xff1a;https://download.csdn.net/download/Highning0007/88198766...

VS Code配置Prettier格式化Apex

先决条件 安装nodejs和npm安装vs code安装salesforce extension pack 配置Prettier Apex 创建本地Salesforce项目 (Standard) command shift p -> SFDX: Create Project with Manifest -> Standard 打开terminal运行npm init生成package.json文件 安装prettier ap…...

Spring-Cloud-Loadblancer详细分析_4

在RoundRobinLoadBalancer.choose中的serviceInstanceListSupplierProvider就是获取服务列表的关键&#xff0c;那么此对象是怎么拿到的呢&#xff0c;让我们回到RoundRobinLoadBalancer的创建过程 Configuration(proxyBeanMethods false) ConditionalOnDiscoveryEnabled pub…...

【根据当天日期输出明天的日期(需对闰年做判定)。】2022-5-15

缘由根据当天日期输出明天的日期(需对闰年做判定)。日期类型结构体如下&#xff1a; struct data{ int year; int month; int day;};-编程语言-CSDN问答 struct mdata{ int year; int month; int day; }mdata; int 天数(int year, int month) {switch (month){case 1: case 3:…...

label-studio的使用教程(导入本地路径)

文章目录 1. 准备环境2. 脚本启动2.1 Windows2.2 Linux 3. 安装label-studio机器学习后端3.1 pip安装(推荐)3.2 GitHub仓库安装 4. 后端配置4.1 yolo环境4.2 引入后端模型4.3 修改脚本4.4 启动后端 5. 标注工程5.1 创建工程5.2 配置图片路径5.3 配置工程类型标签5.4 配置模型5.…...

前端倒计时误差!

提示:记录工作中遇到的需求及解决办法 文章目录 前言一、误差从何而来?二、五大解决方案1. 动态校准法(基础版)2. Web Worker 计时3. 服务器时间同步4. Performance API 高精度计时5. 页面可见性API优化三、生产环境最佳实践四、终极解决方案架构前言 前几天听说公司某个项…...

安宝特方案丨XRSOP人员作业标准化管理平台:AR智慧点检验收套件

在选煤厂、化工厂、钢铁厂等过程生产型企业&#xff0c;其生产设备的运行效率和非计划停机对工业制造效益有较大影响。 随着企业自动化和智能化建设的推进&#xff0c;需提前预防假检、错检、漏检&#xff0c;推动智慧生产运维系统数据的流动和现场赋能应用。同时&#xff0c;…...

鸿蒙中用HarmonyOS SDK应用服务 HarmonyOS5开发一个医院查看报告小程序

一、开发环境准备 ​​工具安装​​&#xff1a; 下载安装DevEco Studio 4.0&#xff08;支持HarmonyOS 5&#xff09;配置HarmonyOS SDK 5.0确保Node.js版本≥14 ​​项目初始化​​&#xff1a; ohpm init harmony/hospital-report-app 二、核心功能模块实现 1. 报告列表…...

Python如何给视频添加音频和字幕

在Python中&#xff0c;给视频添加音频和字幕可以使用电影文件处理库MoviePy和字幕处理库Subtitles。下面将详细介绍如何使用这些库来实现视频的音频和字幕添加&#xff0c;包括必要的代码示例和详细解释。 环境准备 在开始之前&#xff0c;需要安装以下Python库&#xff1a;…...

爬虫基础学习day2

# 爬虫设计领域 工商&#xff1a;企查查、天眼查短视频&#xff1a;抖音、快手、西瓜 ---> 飞瓜电商&#xff1a;京东、淘宝、聚美优品、亚马逊 ---> 分析店铺经营决策标题、排名航空&#xff1a;抓取所有航空公司价格 ---> 去哪儿自媒体&#xff1a;采集自媒体数据进…...

AI书签管理工具开发全记录(十九):嵌入资源处理

1.前言 &#x1f4dd; 在上一篇文章中&#xff0c;我们完成了书签的导入导出功能。本篇文章我们研究如何处理嵌入资源&#xff0c;方便后续将资源打包到一个可执行文件中。 2.embed介绍 &#x1f3af; Go 1.16 引入了革命性的 embed 包&#xff0c;彻底改变了静态资源管理的…...

分布式增量爬虫实现方案

之前我们在讨论的是分布式爬虫如何实现增量爬取。增量爬虫的目标是只爬取新产生或发生变化的页面&#xff0c;避免重复抓取&#xff0c;以节省资源和时间。 在分布式环境下&#xff0c;增量爬虫的实现需要考虑多个爬虫节点之间的协调和去重。 另一种思路&#xff1a;将增量判…...

Java数值运算常见陷阱与规避方法

整数除法中的舍入问题 问题现象 当开发者预期进行浮点除法却误用整数除法时,会出现小数部分被截断的情况。典型错误模式如下: void process(int value) {double half = value / 2; // 整数除法导致截断// 使用half变量 }此时...