Educational Codeforces Round 60 (Rated for Div. 2) C. Magic Ship(二分+前缀和)

版权声明:欢迎转载,若转载,请标明出处,如有错误,请指点,也欢迎大佬们给出优化方法 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;
}

猜你喜欢

转载自blog.csdn.net/Charles_Zaqdt/article/details/87668478
今日推荐