<题目链接>
题目大意:
给定起点和终点,某艘船想从起点走到终点,但是海面上会周期性的刮风,船在任何时候都能够向四个方向走,或者选择不走,船的真正行走路线是船的行走和风的走向叠加的,求船从起点到终点的最小步数。
解题分析:
因为本题数据量十分大,并且船和风叠加的行走路线比较复杂,所以我们考虑用二分答案解题。因为从起点到终点的有效步数是一定的,所以我们可以将船走动的总步数与风的步数(风吹不动的船的步数)分别进行计算,因为风是周期性吹的,但是从起点走到终点不一定是整数个周期,所以我们需要记录每个周期任意时间点所行走的路程前缀。
1 #include <bits/stdc++.h> 2 using namespace std; 3 4 typedef long long ll; 5 #define N int(1e5+7) 6 char s[N]; 7 ll n,sx,sy,ex,ey,nx,ny; 8 ll dx[N],dy[N]; 9 10 bool check(ll step){ //枚举的总步数 11 ll xx=dx[n]*(step/n)+dx[step%n]; //风所移动的距离 12 ll yy=dy[n]*(step/n)+dy[step%n]; 13 return step>=abs(nx-xx)+abs(ny-yy); 14 } 15 int main(){ 16 scanf("%lld%lld%lld%lld",&sx,&sy,&ex,&ey); 17 nx=ex-sx;ny=ey-sy; 18 scanf("%d%s",&n,s+1); 19 for(int i=1;i<=n;i++){ 20 dx[i]=dx[i-1],dy[i]=dy[i-1]; 21 if(s[i]=='U') dy[i]++; //风在竖直方向上的移动 22 if(s[i]=='D') dy[i]--; 23 if(s[i]=='L') dx[i]--; //风在水平方向上的移动 24 if(s[i]=='R') dx[i]++; 25 }//得到周期内竖直和水平方向的前缀位移 26 ll l=0,r=1e18,ans=-1; //二分答案,二分步数 27 while(l<=r){ 28 ll mid=l+r>>1; 29 if(check(mid))ans=mid,r=mid-1; 30 else l=mid+1; 31 } 32 printf("%lld ",ans); 33 }
2019-02-20