Problem - C - Codeforces
你是一艘船的船长。最初你站在一个点(x1,y1)上(很明显,海上的所有位置都可以用笛卡尔平面描述),你想要前往一个点(x2,y2)。
你知道天气预报——长度为n的字符串s,仅由字母U、D、L和R组成。该字母对应于风的方向。此外,预报是周期性的,例如第一天,风朝着s1的方向吹,第二天——s2,第n天——sn,第(n+1)天——再次变成s1,如此循环。
船的坐标改变如下:
如果风朝方向U吹,则船从(x,y)移动到(x,y+1); 如果风朝方向D吹,则船从(x,y)移动到(x,y−1); 如果风朝方向L吹,则船从(x,y)移动到(x−1,y); 如果风朝方向R吹,则船从(x,y)移动到(x+1,y)。 船还可以沿四个方向之一行进或停留在原地。如果船行进,则距离恰好为1个单位。船和风的置换相加。如果船停留在原地,则仅计算风的方向。例如,如果风朝方向U吹,并且船向左移动,则从点(x,y)移动到点(x−1,y+1),如果朝方向U行进,则它将移动到点(x,y+2)。
你的任务是确定船到达点(x2,y2)所需的最小天数。
输入: 第一行包含两个整数x1和y1(0≤x1,y1≤109)——船的初始坐标。 第二行包含两个整数x2和y2(0≤x2,y2≤109)——目标点的坐标。 保证初始坐标和目标点坐标不同。 第三行包含一个整数n(1≤n≤105)——字符串s的长度。 第四行是字符串s本身,仅由字母U、D、L和R组成。
输出: 唯一的一行应该包含船到达点(x2,y2)所需的最小天数。 如果不可能则打印"-1"。
Examples
input
Copy
0 0 4 6 3 UUU
output
Copy
5
input
Copy
0 3 0 0 3 UDD
output
Copy
3
input
Copy
0 0 0 1 1 L
output
Copy
-1
注
在第一个示例中,船舶应执行以下移动顺序:“RRRRU”,然后其坐标将相应更改:(0,0)→(1,1)→(2,2)→(3,3)→(4,4)→(4,6)。
在第二个例子中,船应该执行以下顺序的移动:“DD”(第三天它应该呆在原地)。然后它的坐标将相应地改变:(0,3)→(0,3)→(0,1)→(0,0)。
在第三个例子中,船永远无法到达点(0,1)。
题解:
我们首先记录,在没有人力,只按照风力的情况下,n天内,dx[i],dy[i](船可以在x轴,y轴走多远)
假设经历x天,那么在无人力的情况下,(船可以在x轴,y轴走多远)
tx = x/n*dx[n] + dx[x%n]
ty = x/n*dy[n] + dy[x%n]
要想sx到ex,sy到ey
分别要在x轴走ex - sx,y轴走ey - sy
然后我们看x轴ex - sx与tx的差值绝对值,代表需要人工走多少步才能修正
y轴同理
得到得两个值相加看是否小于x天(人工可以修改的距离)
二分即可
#include <cstdio>
#include <cstring>
#include <algorithm>
#include<iostream>
#include<vector>
#include<set>
#include<map>
#include<cmath>
#include<queue>
using namespace std;
typedef long long ll;
#define int long long
typedef pair<int,int> PII;
int mod = 1e9 + 7;
int n;
int dx[100040];
int sx,sy,ex,ey;
int dy[100040];
int check(int x)
{
int tx = x/n*dx[n] + dx[x%n];
int ty = x/n*dy[n] + dy[x%n];
if(abs(tx - (ex - sx)) + abs(ty - (ey - sy)) <= x)
{
return 1;
}
return 0;
}
void solve()
{
cin >> sx >> sy >> ex >> ey;
cin >> n;
string s;
cin >> s;
s = " " + s;
for(int i = 1;i <= n;i++)
{
dx[i] = dx[i] + dx[i - 1];
dy[i] = dy[i] + dy[i - 1];
if(s[i] == 'U')
{
dy[i] ++;
}
if(s[i] == 'D')
{
dy[i] --;
}
if(s[i] == 'L')
{
dx[i]--;
}
if(s[i] == 'R')
{
dx[i]++;
}
}
int ans = -1;
int l = 0,r = 1e18;
while(l <= r)
{
int mid = (l + r)/2;
if(check(mid))
{
ans = mid;
r = mid - 1;
}
else
{
l = mid + 1;
}
}
cout << ans;
}
//5 7 8 9 10
signed main()
{
// ios::sync_with_stdio(0);
// cin.tie(0);cout.tie(0);
int t = 1;
// cin >> t;
while(t--)
{
solve();
}
}