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

    2019-02-20

  • 相关阅读:
    水题大战Vol.3 B. DP搬运工2
    火题小战 C. 情侣?给我烧了!
    火题小战 B. barbeque
    火题小战 A.玩个球
    P6087 [JSOI2015]送礼物 01分数规划+单调队列+ST表
    NOI2020D1T1美食家
    Java 的随机数
    MySQL 配置文件的配置
    NOIP2020准(ge)备(zi)日记
    android开发EditText禁止输入中文密码的解决方法
  • 原文地址:https://www.cnblogs.com/00isok/p/10409770.html
Copyright © 2020-2023  润新知