【Educational Codeforces Round 53 (Rated for Div. 2)-C. Vasya and Robot】二分

Educational Codeforces Round 53 (Rated for Div. 2) C. Vasya and Robot

题意

在 二 维 平 面 上 有 一 个 机 器 人 最 开 始 在 点 ( 0 , 0 ) 处 在二维平面上有一个机器人最开始在点(0,0)处 (0,0)
最 终 他 要 走 到 点 ( x , y ) 处 , 现 在 给 出 行 动 路 线 , 有 ( L , R , U , D ) 四 种 走 法 最终他要走到点(x,y)处,现在给出行动路线,有(L,R,U,D)四种走法 (x,y),线(L,R,U,D)
每 次 他 可 以 修 改 某 个 区 间 内 的 走 法 , 问 需 要 修 改 的 最 小 区 间 长 度 是 多 少 每次他可以修改某个区间内的走法,问需要修改的最小区间长度是多少
( 区 间 内 可 以 修 改 为 任 意 走 法 , 也 可 以 不 修 改 ) (区间内可以修改为任意走法,也可以不修改)
n &lt; = 2 ∗ 1 0 5 n&lt;=2*10^5 n<=2105

做法

这 个 数 据 范 围 大 概 只 能 想 二 分 , 二 分 长 度 之 后 枚 举 每 个 点 作 为 区 间 起 点 是 否 能 走 到 ( x , y ) 这个数据范围大概只能想二分,二分长度之后枚举每个点作为区间起点是否能走到(x,y) (x,y)
c h e c k 的 过 程 就 是 先 把 区 间 之 外 的 走 法 走 完 , 得 到 ( x 1 , y 1 ) check的过程就是先把区间之外的走法走完,得到(x1,y1) check(x1,y1)
再 判 断 ( x 1 , y 1 ) 与 ( x , y ) 的 曼 哈 顿 距 离 D 再判断(x1,y1)与(x,y)的曼哈顿距离D (x1,y1)(x,y)D
如 果 当 前 区 间 长 度 l e n &gt; D 而 且 ( l e n − D ) M o d 2 = = 0 , 就 代 表 机 器 人 可 以 通 过 当 前 区 间 走 到 ( x , y ) 如果当前区间长度len&gt;D而且(len-D)Mod2==0,就代表机器人可以通过当前区间走到(x,y) len>DlenD)Mod2==0(x,y)
代码

#include<stdio.h>
#include<iostream>
#include<algorithm>
#include<map>
using namespace std;
#define dbg(x) cout<<#x<<" = "<<x<<endl
const int maxn = 2e5+10;
char s[maxn];
int x,y;
int n,sum[maxn][4];//U D L R
map<char,int> mp;
int n1,n2,n3,n4;
bool check(int mid)
{
    int sum1=0,sum2=0,sum3=0,sum4=0;
    for(int i=1;i<=n-mid+1;i++)
    {
        sum1=sum[i-1][0]+sum[n][0]-sum[i+mid-1][0];
        sum2=sum[i-1][1]+sum[n][1]-sum[i+mid-1][1];
        sum3=sum[i-1][2]+sum[n][2]-sum[i+mid-1][2];
        sum4=sum[i-1][3]+sum[n][3]-sum[i+mid-1][3];
        int xx=0,yy=0;
        n1=0,n2=0,n3=0,n4=0;
        xx+=(sum4-sum3);
        yy+=(sum1-sum2);
        if(xx>=x) n3=xx-x;
        else n4=x-xx;
        if(yy>=y) n2=yy-y;
        else n1=y-yy;
        if(n1+n2+n3+n4<=mid&&(mid-n1-n2-n3-n4)%2==0) return true;
    }
    return false;
}
int main()
{
    mp['U']=0;
    mp['D']=1;
    mp['L']=2;
    mp['R']=3;
    scanf("%d%s",&n,s+1);
    for(int i=1;i<=n;i++)
    {
        sum[i][0]=sum[i-1][0];
        sum[i][1]=sum[i-1][1];
        sum[i][2]=sum[i-1][2];
        sum[i][3]=sum[i-1][3];
        sum[i][mp[s[i]]]++;
    }
    scanf("%d%d",&x,&y);
    int l=0,r=n,mid;
    while(l<=r)
    {
        int mid=(l+r)/2;
        if(check(mid)) r=mid-1;
        else l=mid+1;
    }
    if(l==n+1) printf("-1\n");
    else printf("%d\n",l);
    return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值