Educational Codeforces Round 60 (Rated for Div. 2)C. Magic Ship(二分+思维)

时间:2019-02-19
本文章向大家介绍Educational Codeforces Round 60 (Rated for Div. 2)C. Magic Ship(二分+思维),主要包括Educational Codeforces Round 60 (Rated for Div. 2)C. Magic Ship(二分+思维)使用实例、应用技巧、基本知识点总结和需要注意事项,具有一定的参考价值,需要的朋友可以参考一下。

题目链接:https://codeforces.com/contest/1117/problem/C

 

题目大意:有一艘船在x1,y1点,要去x2,y2点,风向按照n天一循环的顺序出现,船可以在有风向的情况下自主选择去一个方向,问最少花多少天到达目的地。

 

题目思路:如果直接求最少天,以及每次都分析朝哪个方向对于这道题无从下手。那么首先可以发现,方向只跟出现的次数有关,跟顺序无关。那么可以将风向导致的位置偏移和船自主的动向分开,先让船随波游荡,然后再进行出发。如果在没有风向的情况下,易得最少天数是曼哈顿距离,那么只要最少天数>=曼哈顿距离就一定能到(多了的天数可以通过与风向抵消来消耗)。再换个角度,如果一个点在有一时刻可以归位,那么他可以选择在这里跟后面所有的风向抵挡来保持原位,由此我们可以得出,只要大于最小天数就一定可以到达目的地,这样我们就可以进行二分,假设天数是x天,然后不断进行模拟即可。

 

以下是代码:

#include<bits/stdc++.h>
using namespace std;
#define inf 0x3f3f3f3f
#define rep(i,a,b) for(int i=a;i<=b;i++)
#define per(i,a,b) for(int i=a;i>=b;i--)
#define ll long long
using namespace std;
const int MAXN = 2e5+5;
const int MOD = 1e9 + 7;
ll xx,yy,x2,y2,n,posx,posy;
char s[MAXN];
bool check(ll x){
    ll ansx=xx+(x/n)*posx;
    ll ansy=yy+(x/n)*posy;
    ll temp=x%n;
    rep(i,0,temp-1){
        if(s[i]=='U')ansy++;
        else if(s[i]=='D')ansy--;
        else if(s[i]=='L')ansx--;
        else if(s[i]=='R')ansx++;
    }
    return abs(ansx-x2)+abs(ansy-y2)<=x;
}
int main()
{
    while(~scanf("%I64d%I64d%I64d%I64d%I64d%s",&xx,&yy,&x2,&y2,&n,s)){
        posx = 0,posy = 0;
        rep(i,0,n-1){
            if(s[i]=='U')posy++;
            else if(s[i]=='D')posy--;
            else if(s[i]=='L')posx--;
            else if(s[i]=='R')posx++;
        }
        ll l = 0,r = 1ll<<60,ans = -1;
        while(l <= r){
            ll mid = (l+r)>>1;
            if(check(mid)){
                r = mid-1;
                ans = mid;
            }
            else l = mid+1;
        }
        printf("%I64d\n",ans);
    }
    return 0;
}