题解-Magic Ship
你在 \((x_1,y_1)\),要到点 \((x_2,y_2)\)。风向周期为 \(n\),一个字符串 \(s\{n\}\) 表示风向(每轮上下左右),每轮你都会被风向吹走一格。你可以在被风吹得被动移动的基础上选择每轮移动一格或不移动。求最少几轮可以到达终点。
数据范围:\(0\le x_1,y_1,x_2,y_2\le 10^9\),\(1\le n\le 10^5\)。
一句话题解:在最优行进策略中,人离终点的距离与风周期数之间的函数单调递减;二分答案轮数。
蒟蒻的前置准备:
先通过坐标系平移简化计算:将起点 \(start\) 置为原点,则终点 \(end\) 为 \((x_2-x_1, y_2-y_1)\)。
风向字符 \(s_i\) 对应的四个字符 \('U'\),\('D'\),\('L'\),\('R'\) 分别表示上下左右走一格,对应位移向量 \(\textrm{w}\) 为:
\(\textrm{w}('U')=(0,1)\),\(\textrm{w}('D')=(0,-1)\),\(\textrm{w}('L')=(-1,0)\),\(\textrm{w}('R')=(1,0)\),字符 \(s_i\) 对应的位移向量 \(\vec{m_i}=\textrm{w}(s_i)\)。
令位移前缀和为:\(\vec{ad_i}=\sum_{j=1}^i \vec{m_i}\),则一个风周期的总位移为 \(\vec{ad_n}\)。
上式表明:尽管在一个长度为 \(n\) 轮的风周期内,人被移动的轨迹是复杂的,但每个风周期对人的轨迹影响是恒定的。因此按风周期来看,人的移动与风周期之间的关系是线性的。
设当前走了 \(k\) 轮:
假如不考虑人主动的走动,只考虑风吹人动,那么人的位置为 \(\left(ad_{k\bmod n}+ad_{n}\cdot \lfloor\frac kn\rfloor\right)\):

这时再考虑人的主动走动,在 \(k\) 轮中人最多走 \(k\) 步。
令 \(\textrm{dis}(a,b)\) 表示 \(a\) 和 \(b\) 两点间的曼哈顿距离(\(x\) 轴距离与 \(y\) 轴距离之和)。
所以如果 \(\textrm{dis}(end,now)\le k\),那么 \(k\) 轮以内即可到达终点。
找到单调性:
对于式子 \(\left(ad_{k\bmod n}+ad_{n}\cdot \lfloor\frac kn\rfloor\right)\):
如果枚举 \(i=k\bmod n\),则点 \(now\) 的移动轨迹可以是一条直线。

这时单独考虑 \(\textrm{dis}(end,now)\):

可以发现 \(\lfloor\frac kn\rfloor\leftrightarrow\textrm{dis}(end,now)\) 的函数图像如下:(如果随风就能飘到终点,折线能与 \(\lfloor\frac kn\rfloor\) 轴相切)

因为最终要比较 \(\textrm{dis}(end,now)\) 和 \(k\),所以作函数 \(\lfloor\frac kn\rfloor\leftrightarrow\textrm{dis}(end,now)-k\):

这时有个问题:这折线是否单调递减?蒟蒻拿图说服你你肯定不信,但是可以这么想:
目的是距离终点更近,风力和人力相等,所以就算风再捣乱,如果人走得和风对着干,与终点的距离也不会变大。
所以这个折线是单调递减的。
可是其实还有一种情况——该折线有平行于 \(\lfloor\frac kn\rfloor\) 轴的一段且与 \(\lfloor\frac kn\rfloor\) 轴没有交点,便说明对于当前的 \(i=k\bmod n\) 无解。
上文提到:
如果 \(\textrm{dis}(end,now)\le k\),那么 \(k\) 轮以内即可到达终点。
所以可以先如上文枚举 \(i=k\bmod n\),然后二分 \(\lfloor\frac kn\rfloor\),得到 \(\lfloor\frac kn\rfloor\leftrightarrow\textrm{dis}(end,now)-k\) 图像上 \(\le 0\) 的临界点整数 \(\lfloor\frac kn\rfloor\),\(k\) 就是对于这个 \(i\) 的答案。总答案是对于每个 \(i\) 的答案的最小值,如果对于每个 \(i\) 都无解,输出 \(-1\)。
如上图,\(\lfloor\frac kn\rfloor=2\),可以通过 \(i\) 推算出 \(k\)。
好了,小蒟蒻成功写出了一篇没人看得懂的题解。还是放代码吧(其实很短):
#include <bits/stdc++.h>
using namespace std;
//Start
#define lng long long
#define db double
#define mk make_pair
#define pb push_back
#define fi first
#define se second
#define rz resize
#define sz(x) (int)((x).size())
const int inf=0x3f3f3f3f;
const lng INF=0x3f3f3f3f3f3f3f3f;
//Data
const int N=1e5;
int n; char s[N+7];
lng ans=INF;
//Point
typedef pair<lng,lng> point;
point st,ed,ad[N+7];
lng dis(point x,point y){return abs(x.fi-y.fi)+abs(x.se-y.se);}
point operator-(const point x,const point y){return mk(x.fi-y.fi,x.se-y.se);}
point operator+(const point x,const point y){return mk(x.fi+y.fi,x.se+y.se);}
point operator*(const point x,const lng y){return mk(x.fi*y,x.se*y);}
//Main
int main(){
scanf("%lld%lld%lld%lld%d%s",&st.fi,&st.se,&ed.fi,&ed.se,&n,&s[1]);
ed=ed-st;
if(ed.fi==0&&ed.se==0) return puts("0"),0;
for(int i=1;i<=n;i++)
if(s[i]=='U') ad[i]=ad[i-1]+mk(0,1);
else if(s[i]=='D') ad[i]=ad[i-1]+mk(0,-1);
else if(s[i]=='L') ad[i]=ad[i-1]+mk(-1,0);
else if(s[i]=='R') ad[i]=ad[i-1]+mk(1,0);
for(int i=1;i<=n;i++){
lng l=-1,r=1e12+1;
while(l<r-1){
lng mid((l+r)>>1);
if(dis(ad[i]+ad[n]*(mid),ed)-mid*n-i<=0) r=mid;
else l=mid;
}
if(dis(ad[i]+ad[n]*r,ed)-r*n-i<=0) ans=min(ans,r*n+i);
}
if(ans==INF) puts("-1");
else printf("%lld\n",ans);
return 0;
}
祝大家学习愉快!
题解-Magic Ship的更多相关文章
- Educational Codeforces Round 60 (Rated for Div. 2) - C. Magic Ship
Problem Educational Codeforces Round 60 (Rated for Div. 2) - C. Magic Ship Time Limit: 2000 mSec P ...
- C. Magic Ship cf 二分
C. Magic Ship time limit per test 2 seconds memory limit per test 256 megabytes input standard input ...
- CF1117C Magic Ship
CF1117C Magic Ship 考虑到答案具单调性(若第 \(i\) 天能到达目的点,第 \(i+1\) 天只需向风向相反的方向航行),可以二分答案. 现在要考虑给出一个天数 \(m\) ,问 ...
- 【Codeforces 1117C】Magic Ship
[链接] 我是链接,点我呀:) [题意] 题意 [题解] 我们可以把这个行船的过程分解成两个过程 1.船经过时间t被风吹到了某个地方 2.船用这t时间尝试到达终点(x2,y2) 会发现如果时间t能最终 ...
- Educational Codeforces Round 60 (Rated for Div. 2) 即Codeforces Round 1117 C题 Magic Ship
time limit per test 2 second memory limit per test 256 megabytes input standard inputoutput standard ...
- CodeForces 1117C Magic Ship (循环节+二分答案)
<题目链接> 题目大意: 给定起点和终点,某艘船想从起点走到终点,但是海面上会周期性的刮风,船在任何时候都能够向四个方向走,或者选择不走,船的真正行走路线是船的行走和风的走向叠加的,求船从 ...
- C. Magic Ship (思维+二分)
https://codeforces.com/contest/1117/problem/C 你是一个船长.最初你在点 (x1,y1) (显然,大海上的所有点都可以用平面直角坐标描述),你想去点 (x2 ...
- 【Codeforces1117C_CF1117C】Magic Ship(构造)
题目: Codeforces1117C 考的时候很困,开局半小时后才过A,只做出来AB,排名3000+,掉了119--半夜体验极差. 翻译: 你是一个船长.最初你在点 \((x_1,y_1)\) (显 ...
- [题解]Magic Line-计算几何(2019牛客多校第三场H题)
题目链接:https://ac.nowcoder.com/acm/contest/883/H 题意: 给你偶数个点的坐标,找出一条直线将这n个点分成数量相等的两部分 并在这条直线上取不同的两个点,表示 ...
随机推荐
- TCP/IP协议图解
联网的各个终端之间能否进行交互的软件基础是网络协议栈,目前主流的网络协议栈是TCP/IP协议栈. 1.主机到网络层协议:以太网协议 主机到网络层主要为IP协议和ARP协议提供服务.发送和接收网络数据报 ...
- showengineinnodbstatus的解读
如何查看innodb的相关信息 ---------------------- BUFFER POOL AND MEMORY ---------------------- Total memory al ...
- NOIP前一些题目的理解
ZYB和售货机(图论,环) 题目链接 个人感觉这道题与基环树没有任何关系,你会发现,每个点最多只有一个入度和出度,所以只能是链或环. 还有就是本题的突破点就在于正确建图,题目的限制保证每个点的入度不大 ...
- 【python爬虫】用requests库模拟登陆人人网
说明:以前是selenium登陆取cookie的方法比较复杂,改用这个 """ 用requests库模拟登陆人人网 """ import r ...
- rinetd小工具
一.介绍 tcp端口转发工具,针对ip:port的 连接进行转发.重点开源,且配置简单.不支持ftp,因为ftp要使用多个端口. 1.转发规则 [root@master tmp]# cat a.con ...
- 插件Spire.PDF帮你高效搞定PDF打印
Spire.PDF介绍 Spire.PDF是一个专业的PDF组件,能够独立地创建.编写.编辑.操作和阅读PDF文件,支持 .NET.Java.WPF和Silverlight.Spire.PDF的PDF ...
- 如何调整MathType公式的字体大小
作为一名理科生,想必大家都在为编辑公式而烦恼,在Word中要想完美插入公式,还真不是那么简单的.首先要使用专业的公式编辑器MathType,其次还要对公式的大小进行修改,这样才能看起来是相融合的文章. ...
- jQuery 第七章 实例方法 位置图形
位置坐标图形大小相关方法: .offset() .position() .scrollTop() .scrollLeft() .width() .height() .innerWidth() inne ...
- 【PYTEST】第一章常用命令
pytest入门 安装pytest 运行pytest pytest常用命令 1. 安装pytest pip install pytest 2. 运行pytest 2.1 pytest默认搜索当前目录下 ...
- 与运算(&)、或运算(|)、异或运算(^)、右移运算符(>>>)本质介绍
按位与运算符(&) 参加运算的两个数据,按二进制位进行"与"运算. 运算规则:0&0=0; 0&1=0; 1&0=0; 1&1= ...