版权声明:欢迎转载,若转载,请标明出处,如有错误,请指点,也欢迎大佬们给出优化方法 https://blog.csdn.net/Charles_Zaqdt/article/details/87668478
题目链接:https://codeforces.com/contest/1117/problem/C
题意是有一艘船,输入了起点和终点的坐标,还输入了长度为n的字符串,字符串中表示第i天的风向,根据题目上的描述,每一天的风向都会使船移动一个单位,当然船每天也可以自己移动一个单位,问最少多少天能到达终点,始终不能到达就输出-1。
题目看上去是一道模拟题,但是正解还是很巧妙的,感觉不是很好想...求出来风向的前缀和(也就是求出第i天船能被刮多远),然后二分天数看是否可行。因为风刮的移动是无法改变的,自己走的话肯定是走最优的结果,我们二分一个天数m,然后根据前缀和算出来经过m天,船被刮到了哪个位置(这个过程可以看作船自己没有走,只靠风刮),然后在算出这个位置到终点的距离能否在m天让船自己走完就好了。
AC代码:
#include <bits/stdc++.h>
#define maxn 100005
#define ll long long
using namespace std;
int x1,y11,x2,y2;
int n;
int dx[maxn], dy[maxn];
string str;
bool Check(ll m){
ll a = m / n;
ll b = m % n;
ll x = a * dx[n] + dx[b] + x1;
ll y = a * dy[n] + dy[b] + y11;
ll ans = abs(x2 - x) + abs(y2 - y);
return ans <= m;
}
int main()
{
cin>>x1>>y11>>x2>>y2;
cin>>n>>str;
for(int i=0;i<n;i++){
dy[i+1] = dy[i];
dx[i+1] = dx[i];
if(str[i] == 'U') dy[i+1] ++;
if(str[i] == 'D') dy[i+1] --;
if(str[i] == 'L') dx[i+1] --;
if(str[i] == 'R') dx[i+1] ++;
}
ll l = 0, r = 1e18, mid, ans = -1;
while(l <= r){
mid = (l + r) >> 1;
if(Check(mid)){
r = mid - 1;
ans = mid;
}
else l = mid + 1;
}
cout<<ans<<endl;
return 0;
}