EducationalCodeforcesRound60C. Magic Ship

You a captain of a ship. Initially you are standing in a point (x1,y1) (obviously, all positions in the sea can be described by cartesian plane) and you want to travel to a point (x2,y2).

You know the weather forecast — the string s of length n, consisting only of letters U, D, L and R. The letter corresponds to a direction of wind. Moreover, the forecast is periodic, e.g. the first day wind blows to the side s1, the second day — s2, the n-th day — sn and (n+1)-th day — s1 again and so on.

Ship coordinates change the following way:
if wind blows the direction U, then the ship moves from (x,y) to (x,y+1);
if wind blows the direction D, then the ship moves from (x,y) to (x,y−1);
if wind blows the direction L, then the ship moves from (x,y) to (x−1,y);
if wind blows the direction R, then the ship moves from (x,y) to (x+1,y) .

The ship can also either go one of the four directions or stay in place each day. If it goes then it’s exactly 1 unit of distance. Transpositions of the ship and the wind add up. If the ship stays in place, then only the direction of wind counts. For example, if wind blows the direction U and the ship moves the direction L, then from point (x,y)
it will move to the point (x−1,y+1), and if it goes the direction U, then it will move to the point (x,y+2).
You task is to determine the minimal number of days required for the ship to reach the point (x2,y2).

Input
The first line contains two integers x1,y1(0≤x1,y1≤109) — the initial coordinates of the ship.
The second line contains two integers x2,y2(0≤x2,y2≤109) — the coordinates of the destination point.
It is guaranteed that the initial coordinates and destination point coordinates are different.
The third line contains a single integer n(1≤n≤105) — the length of the string s.
The fourth line contains the string s itself, consisting only of letters U, D, L and R.

Output
The only line should contain the minimal number of days required for the ship to reach the point (x2,y2).If it’s impossible then print “-1”.

Examples
Input

0 0
4 6
3
UUU

Output

5

Input

0 3
0 0
3
UDD

Output

3

Input

0 0
0 1
1
L

Output

-1

有个船在海上漂,能开能跑看心情,顺风相加逆风减,最少几天能到啊!
注意,给出的未来的风向预测是指,未来的风向将按照这个顺序循环刮。
根据题意与数据量,可以采用二分枚举答案的方法,判断当前天数是否能到达,如果能到达,则进一步缩短天数;若不能到达,就增加天数。这样不断缩小可能区间,直到找出最小到达天数。
其次再考虑如何实现判断某一天数是否能到达。根据题意,在航行过程中,某一天是否开船是随意的,在这里不妨将其拆分成两部分:
一是船从出发点(S)完全不发动仅靠风所能到达的位置,记作T;
二是在无风的情况下,船向着目的地(D)开动。注意两者所用天数应相同。
这样,只要T与D的曼哈顿距离 <= 所用天数,那么船就可以到达目的地;否则不能到达。
之后考虑不能到达的情况,根据题意可知,最差情况是出发点与目的点只在一个方向上相差1e9,而每隔1e5天才能在这个方向上移动一步,这样所用最短天数是1e14,所以如果求出的天数 > 1e14 ,那么就可以判定这种情况是不能到达的。


#include <stdio.h>
#include <climits>
#include <cstring>
#include <time.h>
#include <math.h>
#include <iostream>
#include <algorithm>
#include <stack>
#include <queue>
#include <set>
#include <map>
#include <utility>
#include <vector>
#include <string>

#define INF 0x3f3f3f3f
#define ll long long
#define Pair pair<int,int>
#define re return

#define Make(a,b) make_pair(a,b)
#define Push(num) push_back(num)
#define rep(index,star,finish) for(register int index=star;index<finish;index++)
#define drep(index,finish,star) for(register int index=finish;index>=star;index--)
using namespace std;

int X1,Y1;
int X2,Y2;
int n;
vector<char> forecast(100024);
int statistics[4][100024];
/*
    0   U
    1   D
    2   L
    3   R
*/

inline bool mulPos(int s,int f);
inline int Tr(char s);
bool judge(ll day);    //if can reach return true,else return false
int main(){
    ios::sync_with_stdio(false);

    cin>>X1>>Y1;
    cin>>X2>>Y2;
    if(X1==X2 && Y1==Y2){
        cout<<0<<endl;
        return 0;
    }
    cin>>n;
    rep(i,1,n+1)
        cin>>forecast[i];

    memset(statistics,0,sizeof(statistics));
    rep(i,0,4)
        statistics[i][0]=0;
    rep(i,1,n+1){
        statistics[Tr(forecast[i])][i]++;
        rep(j,0,4)
            statistics[j][i]+=statistics[j][i-1];
    }

    ll inf=-1,sup=1e16+5;
    while(inf+1<sup){
        ll mid=inf+(sup-inf)/2;

        if(judge(mid)){
            sup=mid;
        }else{
            inf=mid;
        }
    }

    if(sup>1e16)
        cout<<"-1"<<endl;
    else
        cout<<sup<<endl;
    re 0;
}
inline bool mulPos(int s,int f){

}
inline int Tr(char s){
    if(s=='U')
        return 0;
    else
        if(s=='D')
            return 1;
        else
            if(s=='L')
                return 2;
            else
                if(s=='R')
                    return 3;
                else
                    return -1;
}

bool judge(ll day){
    //in peace ,the move out of wind
    int turnU=statistics[0][n]-statistics[1][n];
    int turnR=statistics[3][n]-statistics[2][n];
    ll t=1LL*day/n , res=day%n;
    ll staU=1LL*turnU*t+statistics[0][res]-statistics[1][res];
    ll staR=1LL*turnR*t+statistics[3][res]-statistics[2][res];
    //in fact,should move
    ll facU=Y2-Y1;
    ll facR=X2-X1;

    //make up distance,in vertical and level
    ll ver=max(facU,staU)-min(facU,staU);
    ll hor=max(facR,staR)-min(facR,staR);
    if(ver+hor<=day)
        return true;
    else
        return false;
}

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值