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;
}

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

tomcat服务七层搭建动态页面查看

一个服务器多实例复制完成 配置tomcat多实例的环境变量 vim /etc/profile.d/tomcat.sh配置tomcat1和tomcat2的环境变量 进入tomcat1修改配置 测试通信端口是否正常 连接正常 toncat 2 配置修改 修改这三个 端口配置修改完成 修改tomcat1 shudown 分别把启动文件指向tomcat1…

Spring Cloud 面试突击2

Spring Cloud 面试突击2 高并发&#xff1a;是一种系统运行过程中遇到的短时间大量的请求操作 响应时间&#xff1a; 吞吐量&#xff1a; QPS&#xff1a;数据库为维度 TPS 并发用户数 并发的维度&#xff1a;很多的 并发是不是达到的当前系统的瓶颈 缓存 &#xff08…

2023牛客暑期多校训练营7

Beautiful Sequence 贪心&#xff0c;二进制&#xff0c;构造 Cyperation 模拟 &#xff0c;数学 We Love Strings 分块&#xff0c;二进制枚举&#xff0c;二进制容斥dp Writing Books 签到 根据相邻两个异或值B&#xff0c;因为前小于等于后&#xff0c;故从高到低遍历B的每一…

实验二十六、RC桥式正弦波振荡电路参数选择

一、题目 电路如图1所示。利用 Multisim 分析下列问题&#xff1a; &#xff08;1&#xff09;选择合适的 R f R_f Rf​ 和稳压管&#xff0c;使电路产生正弦波振荡&#xff0c;并观察起振过程&#xff1b; &#xff08;2&#xff09;调整电路参数&#xff0c;使输出电压峰值…

CH342/CH343/CH344/CH347/CH9101/CH9102/CH9103/CH9104 Linux串口驱动使用教程

CH343 Linux串口驱动 ch343ser_linux 支持USB转串口芯片 ch342/ch343/ch344/ch347/ch9101/ch9102/ch9103/ch9104等 &#xff0c;同时该驱动配合ch343_lib库还提供了芯片GPIO接口的读写功能&#xff0c;内部EEPROM的信息配置和读取功能等。 芯片型号串口数量GPIO数量CH342F/K2C…

CCLINK IE FIELD BASIC转MODBUS-TCP网关cclink与以太网的区别

协议的不同&#xff0c;数据读取困难&#xff0c;这是很多生产管理系统的难题。但是现在&#xff0c;捷米JM-CCLKIE-TCP通讯网关&#xff0c;让这个问题变得非常简单。这款通讯网关可以将各种MODBUS-TCP设备接入到CCLINK IE FIELD BASIC网络中&#xff0c;连接到MODBUS-TCP总线…

cpu的架构

明天继续搞一下cache,还有后面的, 下面是cpu框架图 开始解释cpu 1.控制器 控制器又称为控制单元&#xff08;Control Unit&#xff0c;简称CU&#xff09;,下面是控制器的组成 1.指令寄存器IR:是用来存放当前正在执行的的一条指令。当一条指令需要被执行时&#xff0c;先按…

模型性能的主要指标

主要参数 ROC 曲线和混淆矩阵都是用来评估分类模型性能的工具 ROC曲线&#xff08;Receiver Operating Characteristic curve&#xff09;&#xff1a; ROC曲线描述了当阈值变化时&#xff0c;真正类率&#xff08;True Positive Rate, TPR&#xff09;和假正类率&#xff0…

Android Studio跳过Haxm打开模拟器

由于公司权限限制无法安装Haxm&#xff0c;这个时候我们可以试试Arm相关的镜像去跳过Haxm运行模拟器。解决方案&#xff1a;安装API27以下的Arm Image. #ifdef __x86_64__if (sarch "arm64" && apiLevel >28) {APANIC("Avds CPU Architecture %s i…

NPM与外部服务的集成(上)

目录 1、关于访问令牌 1.1 关于传统令牌 1.2 关于粒度访问令牌 2、创建和查看访问令牌 2.1 创建访问令牌 在网站上创建传统令牌 在网站上创建粒度访问令牌 使用CLI创建令牌 CIDR限制令牌错误 查看访问令牌 在网站上查看令牌 在CLI上查看令牌 令牌属性 1、关于访问令…

mysql数据库第十二课------mysql语句的拔高2------飞高高

作者前言 &#x1f382; ✨✨✨✨✨✨&#x1f367;&#x1f367;&#x1f367;&#x1f367;&#x1f367;&#x1f367;&#x1f367;&#x1f382; ​&#x1f382; 作者介绍&#xff1a; &#x1f382;&#x1f382; &#x1f382; &#x1f389;&#x1f389;&#x1f389…

【C++】开源:CGAL计算几何库配置使用

&#x1f60f;★,:.☆(&#xffe3;▽&#xffe3;)/$:.★ &#x1f60f; 这篇文章主要介绍CGAL计算几何库配置使用。 无专精则不能成&#xff0c;无涉猎则不能通。——梁启超 欢迎来到我的博客&#xff0c;一起学习&#xff0c;共同进步。 喜欢的朋友可以关注一下&#xff0c;…

【java】mybatis-plus代码生成

正常的代码生成这里就不介绍了。旨在记录实现如下功能&#xff1a; 分布式微服务环境下&#xff0c;生成的entity、dto、vo、feignClient等等api模块&#xff0c;需要和mapper、service、controller等等分在不同的目录生成。 为什么会出现这个需求&#xff1f; mybatis-plus&am…

【计算机视觉|生成对抗】用深度卷积生成对抗网络进行无监督表示学习(DCGAN)

本系列博文为深度学习/计算机视觉论文笔记&#xff0c;转载请注明出处 标题&#xff1a;Unsupervised Representation Learning with Deep Convolutional Generative Adversarial Networks 链接&#xff1a;[1511.06434] Unsupervised Representation Learning with Deep Conv…

微信小程序中键盘弹起输入框自动跳到键盘上方处理

效果展示 键盘未弹起时 键盘弹起后&#xff1a; 实现方式 话就不多说了 我直接贴代码了 原理就是用你点击的输入框的底部 距离顶部的位置 减去屏幕高度除以2&#xff0c;然后设成负值&#xff0c;再将这个值给到最外层相对定位的盒子的top属性&#xff0c;这样就不会出现顶…

服务器安装JDK

三种方法 方法一&#xff1a; 方法二&#xff1a; 首先登录到Oracle官网下载JDK JDK上传到服务器中&#xff0c;记住文件上传的位置是在哪里&#xff08;我放的位置在/www/java&#xff09;&#xff0c;然后看下面指示进行安装 方法三&#xff1a; 首先登录到Oracle官网下载…

修改IDEA的idea.vmoptions参数导致IDEA无法打开(ReservedCodeCacheSize)

事发原因 Maven导依赖的时候OOM&#xff0c;因此怀疑是内存太小&#xff0c;尝试修改idea.vmoptions的参数&#xff0c;然后发现IDEA重启后打不开了&#xff0c;卸载重装后也无法打开。。。 实际上如果导包爆出OOM的话应该调整下图参数&#xff0c;不过这都是后话了 解决思路…

王道机组难题分析

第四章 指令系统 大端方式&#xff1a;就是高地址存放高位&#xff0c; LSB的意思是&#xff1a;全称为Least Significant Bit&#xff0c;在二进制数中意为最低有效位 MSB的意思是&#xff1a;全称为Most Significant Bit&#xff0c;在二进制数中属于最高有效位 操作数可以理…

HCIP学习--BGP2

目录 前置内容 BGP宣告问题 BGP自动汇总问题 BGP 的认证 BGP的聚合(汇总) 标准的BGP聚合配置 非标准的BGP聚合 路由传递干涉策略 抑制列表 Route-map 分发列表 前缀列表 BGP在MA网络中下一跳问题-ICMP重定向 查看与某个邻居收发的路由 配置 有条件打破IBGP水平…

腾讯云轻量应用服务器镜像应用模板清单大全

腾讯云轻量应用服务器支持多种应用模板镜像&#xff0c;Windows和Linux镜像模板都有&#xff0c;如&#xff1a;宝塔Linux面板腾讯云专享版、WordPress、WooCommerce、LAMP、Node.js、Docker CE、K3s、宝塔Windows面板和ASP.NET等应用模板镜像&#xff0c;腾讯云服务器网分享腾…