CodeForces 1117C Magic Ship (循环节+二分答案)

<题目链接>

题目大意:

给定起点和终点,某艘船想从起点走到终点,但是海面上会周期性的刮风,船在任何时候都能够向四个方向走,或者选择不走,船的真正行走路线是船的行走和风的走向叠加的,求船从起点到终点的最小步数。

解题分析:

因为本题数据量十分大,并且船和风叠加的行走路线比较复杂,所以我们考虑用二分答案解题。因为从起点到终点的有效步数是一定的,所以我们可以将船走动的总步数与风的步数(风吹不动的船的步数)分别进行计算,因为风是周期性吹的,但是从起点走到终点不一定是整数个周期,所以我们需要记录每个周期任意时间点所行走的路程前缀。

 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\n",ans);
33 }

 

 

2019-02-20

转载于:https://www.cnblogs.com/00isok/p/10409770.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值