CF1117C - Magic Ship (二分)
Description
题目大意是,船要从(x1, y1)行驶到(x2, y2),船可以上下左右行驶或呆在原位不动。同时还有风的影响,船的移动和风的影响可以叠加。问船行驶到终点的最少时间的多少?
思路
由于只要每次行驶和风相反的方向,就至少可以保证保持原位不动。所以船要么可以更靠近终点,要么保持不动,这就说明是单调的。所以二分所需的天数,判断只有风的影响下船的位置能否到达终点即可。
上限设置大一些,这样就能保证不能到达终点的情况的正确性。
#include <iostream>
#include <cstdio>
#include <queue>
#include <algorithm>
#include <map>
#include <set>
#include <vector>
#include <cstring>
#include <string>
#include <deque>
#include <cmath>
#include <iomanip>
#include <cctype>
#define endl '\n'
#define IOS std::ios::sync_with_stdio(0);
#define FILE freopen("..//data_generator//in.txt","r",stdin),freopen("res.txt","w",stdout)
#define FI freopen("..//data_generator//in.txt","r",stdin)
#define FO freopen("res.txt","w",stdout)
#define md make_pair
#define pb push_back
#define mp make_pair
#define seteps(N) fixed << setprecision(N)
typedef long long ll;
ll gcd(ll a, ll b) {return b ? gcd(b, a % b) : a;}
inline ll qmul(ll a, ll b, ll m) {
ll res = 0;
while(b) {
if(b & 1) res = (res + a) % m;
a = (a << 1) % m;
b = b >> 1;
}
return res;
}
inline ll qpow(ll a, ll b, ll m) {
ll res = 1;
while(b) {
if(b & 1) res = (res * a) % m;
a = (a * a) % m;
b = b >> 1;
}
return res;
}
inline ll inv(ll x, ll q) {
return qpow(x, q - 2, q);
}
using namespace std;
/*-----------------------------------------------------------------*/
#define INF 0x3f3f3f3f
const int N = 1e6 + 10;
const double eps = 1e5;
char arr[N];
ll dx[N];
ll dy[N];
bool check(ll day, ll n, ll sx, ll sy, ll ex, ll ey) {
ll x = ex - (sx + dx[day % n] + (day / n) * dx[n]);
ll y = ey - (sy + dy[day % n] + (day / n) * dy[n]);
return day >= abs(x) + abs(y);
}
int main() {
IOS;
//FI;
int n;
ll sx, sy;
ll ex, ey;
cin >> sx >> sy >> ex >> ey;
cin >> n;
for(int i = 1; i <= n; i++) {
cin >> arr[i];
if(arr[i] == 'U') dy[i]++;
else if(arr[i] == 'D') dy[i]--;
else if(arr[i] == 'L') dx[i]--;
else if(arr[i] == 'R') dx[i]++;
dx[i] += dx[i - 1];
dy[i] += dy[i - 1];
}
ll l = 0, r = 1e18;
while(l <= r) {
ll mid = (l + r) / 2;
if(check(mid, n, sx, sy, ex, ey)) r = mid - 1;
else l = mid + 1;
}
if(l >= (ll)1e18) cout << -1 << endl;
else cout << l << endl;
}