洛谷上这道题的第一篇题解。上海加油。

题目大意

Aladdin 已经厌倦了宫殿里的生活。他有一份稳定的工作,他的妻子 Jasmine 和孩子们都在路上,生活变得单调。在这一切的驱使下,他决定在安顿下来之前再进行一次冒险。他决定找到 Golden Pear,这是一件极为珍贵的传奇文物,至今无人能找到。

Aladdin 正在寻找的沙漠可以被看作是一个 \(n×n\) 的网格。行和列从上到下、从左到右编号为 \(1\) 到 \(N\)。沙漠中的网格里一共有 \(M\) 个巫师,他们以一种不同寻常的方式帮助 Aladdin 完成任务。

Aladdin 星期一在沙漠的左上角 \((1,1)\) 开始他的任务并面朝右。他的动作包括重复这些步骤:

  • 如果当前的网格里有一个醒着的巫师,那么 Aladdin 会根据巫师说的话向左或向右转 \(90\) 度。
  • 如果向前走会把 Aladdin 带出沙漠,他会转过 \(180\) 度。
  • Aladdin 向前移动了一格,这将花费他一天的时间。

对于每个巫师,我们都知道他的位置和一周中每一天的活动计划。每个巫师的日程表是一个由七个字母(仅包含 LRS)组成的字符串,每个字符告诉我们巫师在一周中的某一天(从星期一开始)做什么。字母 L 表示 Aladdin 将在这一天被告知向左转,R 表示 Aladdin 将在这一天被告知向右转,而 S 表示巫师那天正在睡觉。

一个古老的预言说,在改变 \(K\) 次方向(通过步骤 \(1\) 和步骤 \(2\))后,Aladdin 会找到 Golden Pear。根据古老的预言,写一个程序来计算冒险将持续多少天。

大体思路

按照题意,定义一个状态为 \((x,y,dir,day)\),表示当前位置 \((x,y)\) 在星期 \(day\) 被访问,方向为 \(dir\),其中 \(x,y\le 200\),\(dir=\{0,1,2,3\}\),\(day=\{0,1,2,3,4,5,6\}\)。因此,总的状态数为 \(200^2\times 4\times 7≈10^6\)。所以,我们完全可以用数组直接存储每一个状态。

记 \(turns[x,y,dir,day]\) 表示上一次在星期 \(day\) 以 \(dir\) 方向来到 \((x,y)\) 时转向的次数,而 \(date[x,y,dir,day]\) 则表示上一次在星期 \(day\) 以 \(dir\) 方向来到 \((x,y)\) 时的天数。设当前转向次数为 \(k\),天数为 \(ans\),那么,从上一次访问到这一次访问的循环,转向的次数为 \(\Delta k=k-turns[x,y,dir,day]\),循环的天数为 \(\Delta t=ans - date[x,y,dir,day]\)。

由于距离目标 \(K\) 次转向还有 \(K-k\) 次,可以完成的完整的循环次数为 \(times=\left\lfloor\dfrac{K-k}{\Delta k}\right\rfloor\)。那么,可以直接将转向次数增加 \(\Delta k\times times\),天数增加 \(\Delta t \times times\)。然后,在对 \(date,turns\) 用目前状态的 \(ans,k\) 进行更新即可。

具体实现时,还需要在永久循环的开头判断 LR 以及边界的转向,并调整 \(dir,k\) 等。

完整代码

#include <bits/stdc++.h>
using namespace std;
#define rep(ii,aa,bb) for(re int ii = aa; ii <= bb; ii++)
#define Rep(ii,aa,bb) for(re int ii = aa; ii >= bb; ii--)
typedef long long ll;
typedef unsigned long long ull;
typedef double db;
typedef pair<int, int> PII;
const int maxn = 205;
namespace IO_ReadWrite {
#define re register
#define gg (p1 == p2 && (p2 = (p1 = _buf) + fread(_buf, 1, 1<<21, stdin), p1 == p2) ? EOF :*p1++)
char _buf[1<<21], *p1 = _buf, *p2 = _buf;
template <typename T>
inline void read(T &x){
x = 0; re T f=1; re char c = gg;
while(c > 57 || c < 48){if(c == '-') f = -1;c = gg;}
while(c >= 48 &&c <= 57){x = (x<<1) + (x<<3) + (c^48);c = gg;}
x *= f;return;
}
inline void ReadChar(char &c){
c = gg;
while(!isalpha(c)) c = gg;
}
template <typename T>
inline void write(T x){
if(x < 0) putchar('-'), x = -x;
if(x > 9) write(x/10);
putchar('0' + x % 10);
}
template <typename T>
inline void writeln(T x){write(x); putchar('\n');}
}
using namespace IO_ReadWrite;
int dx[4] = {0, 1, 0, -1},
dy[4] = {1, 0, -1, 0};//right, down, left, up
int N, M, K, turns[maxn][maxn][4][8];
char mp[maxn][maxn][8];
ll date[maxn][maxn][4][8];
int main () {
scanf("%d%d%d", &N, &K, &M);
rep(i, 1, M) {
int x, y;
scanf("%d%d", &x, &y);
scanf("%s", mp[x][y]);
}
ll ans = 0;
int x = 1, y = 1, dir = 0, day = 0, k = 0;
while(1) {
if(mp[x][y][day] == 'L') dir = (dir + 3) % 4, k ++;
if(mp[x][y][day] == 'R') dir = (dir + 1) % 4, k ++;
int nx = x + dx[dir], ny = y + dy[dir];
if(nx < 1 || nx > N || ny < 1 || ny > N) dir = (dir + 2) % 4, k ++;
if(date[x][y][dir][day]) {
int newK = k - turns[x][y][dir][day];
int left = K - k;
ans += (left / newK) * (ans - date[x][y][dir][day]);
k += (left / newK) * newK;
}
date[x][y][dir][day] = ans;
turns[x][y][dir][day] = k;
if(k >= K) break;
x = x + dx[dir], y = y + dy[dir];
ans ++;
if(++day >= 7) day = 0;
}
writeln(ans);
return 0;
}

P7683 [COCI2008-2009#5] KRUSKA的更多相关文章

  1. BZOJ 2039: [2009国家集训队]employ人员雇佣

    2039: [2009国家集训队]employ人员雇佣 Time Limit: 20 Sec  Memory Limit: 259 MBSubmit: 1369  Solved: 667[Submit ...

  2. Step by Step 安装 BizTalk Server 2009

    原创地址:http://www.cnblogs.com/jfzhu/p/4020444.html 转载请注明出处 演示环境为Windows Server 2008 Enterprise, SQL Se ...

  3. BZOJ 2038: [2009国家集训队]小Z的袜子(hose) [莫队算法]【学习笔记】

    2038: [2009国家集训队]小Z的袜子(hose) Time Limit: 20 Sec  Memory Limit: 259 MBSubmit: 7687  Solved: 3516[Subm ...

  4. BZOJ 2463: [中山市选2009]谁能赢呢?

    2463: [中山市选2009]谁能赢呢? Time Limit: 10 Sec  Memory Limit: 128 MBSubmit: 1887  Solved: 1390[Submit][Sta ...

  5. BZOJ 2038: [2009国家集训队]小Z的袜子(hose)

    2038: [2009国家集训队]小Z的袜子(hose) Time Limit: 20 Sec  Memory Limit: 259 MBSubmit: 7676  Solved: 3509[Subm ...

  6. SACS +Petrel 2009地震

    Bentley SACS V8i SS4 05.07.01.01 海洋平台分析Schlumberger Petrel 2009地震解释油藏模拟课程 Trimble Tekla Structural D ...

  7. 彻底卸载 RAD Studio 2009/2010/XE

    彻底卸载 RAD Studio 2009/2010/XE: 控制面板-->添加/删除程序中执行了卸载操作以后, 还需要做以下工作: 1. 删除以下目录(注意有些目录是隐藏的): %ALLUSER ...

  8. DataSnap 2009 系列之三 (生命周期篇)

    DataSnap 2009 系列之三 (生命周期篇) DataSnap 2009的服务器对象的生命周期依赖于DSServerClass组件的设置 当DSServer启动时从DSServerClass组 ...

  9. 莫队算法 2038: [2009国家集训队]小Z的袜子(hose)

    链接:http://www.lydsy.com/JudgeOnline/problem.php?id=2038 2038: [2009国家集训队]小Z的袜子(hose) Time Limit: 20 ...

随机推荐

  1. vivo鲁班RocketMQ平台的消息灰度方案

    一.方案背景 RocketMQ(以下简称MQ)作为消息中间件在事务管理,异步解耦,削峰填谷,数据同步等应用场景中有着广泛使用.当业务系统进行灰度发布时,Dubbo与HTTP的调用可以基于业界通用的灰度 ...

  2. w10环境vs2017,vs2019配置Opengl快捷方法

    最近,计算机图形学老师向我们布置了任务,配置自己的opengl.百度之后我发现很多教程和方法尝试之后,我发现一种简单的方法来分享给大家. 首先我的软件配置是w10专业版系统+Visual Stdio ...

  3. 深度学习(一)之MNIST数据集分类

    任务目标 对MNIST手写数字数据集进行训练和评估,最终使得模型能够在测试集上达到\(98\%\)的正确率.(最终本文达到了\(99.36\%\)) 使用的库的版本: python:3.8.12 py ...

  4. CentOS 通过shell脚本过滤得到服务器IP地址

    1.CentOS 6.x (32Bit &&64Bit) [root@localhost ~]# ifconfig |grep Bcast |awk '{print$2}' |sed ...

  5. Linux 进程打开最大文件连接数Too many open files

    首先出现这个提示的原因:应用程序打开的文件数量超过了系统设定值. 如何查看当前系统每个用户最大允许打开文件数量: [root@registry ~]# ulimit -a core file size ...

  6. HTTP 之 Content-Type

    Content-Type,内容类型,一般是指网页中存在的Content-Type,用于定义网络文件的类型和网页的编码,决定文件接收方将以什么形式.什么编码读取这个文件,这就是经常看到一些Asp网页点击 ...

  7. 内网代理工具--EarthWorm

    一.简介 EarthWorm是内网穿透的神器,拥有三项功能正向代理,反向代理,端口转发. 为实现这些功能,EarthWorm建立了六大功能模块.分别是ssocksd , rcsocks , rssoc ...

  8. CF1404E Bricks (最大权独立集)

    考虑把答案进行转化,通过分矩形条,我们能去掉一些夹在#之间的边 那么答案= #个数 - 能去掉的边个数 但去掉是有限制的,同一个#格子的横边和竖边不能同时去掉 把边转化成点,限制变成边. 横竖边的点 ...

  9. 《前端运维》五、k8s--1安装与基本配置

    一.k8s基础概念与安装 k8s,即kubernetes是用于自动部署,扩展和管理容器化应用程序的开源系统.详细的描述就不多说了,官网有更详细的内容.简单来说,k8s,是一个可以操作多台机器调度部署镜 ...

  10. iOS全埋点解决方案-应用退出和启动

    前言 ​ 通过应用程序退出事件,可以分析应用程序的平均使用时长:通过应用程序的启动事件,可以分析日活和新增.我们可以通过全埋点方式 SDK 实现应用程序的退出和启动事件. 一.全埋点的简介 ​ 目前. ...