Educational Codeforces Round 60 C 思维 + 二分

https://codeforces.com/contest/1117/problem/C

题意

在一个二维坐标轴上给你一个起点一个终点(x,y<=1e9),然后给你一串字符串代表每一秒的风向,然后每一秒你也可以选择一个方向移动,问到达从起点到终点的最短时间

题解

  • 思维:等效法
  • 假如到达终点之后,可以静止不动,可以用自己走反向风方向来抵消风的方向
  • 先只考虑风向,用前缀和将每一秒到达的位置维护出来,假设x秒到达的位置是[x,y],终点为[sx,sy],则若|sx-x|+|sy-y|<=x,则一定可以到达终点,多余的风向走反向来抵消
  • 二分答案

代码

#include<bits/stdc++.h>
#define ll long long 
using namespace std;
ll sx,sy,ex,ey,n,x[100005],y[100005],i,l,r,mid;
char s[100005];
int ok(ll d){
	ll px=sx+d/n*x[n]+x[d%n];
	ll py=sy+d/n*y[n]+y[d%n];
	if(abs(px-ex)+abs(py-ey)<=d)return 1;
	else return 0;
}
int main(){
	cin>>sx>>sy>>ex>>ey>>n;
	scanf("%s",s+1);
	for(i=1;i<=n;i++){
		x[i]=x[i-1];y[i]=y[i-1];
		if(s[i]=='U')y[i]++;
		if(s[i]=='D')y[i]--;
		if(s[i]=='L')x[i]--;
		if(s[i]=='R')x[i]++;
	}
	l=0;r=2e14+1;
	while(l<r){
		mid=(l+r)/2;
		if(ok(mid))r=mid;
		else l=mid+1;
	}
	if(l>2e14)cout<<-1;
	else cout<<l;
}
原文地址:https://www.cnblogs.com/VIrtu0s0/p/10502782.html