Coderforces 1073 C. Vasya and Robot

题意:给一串上下左右的字符串和一个坐标,定义修改操作是修改某个子串,费用为该子串长度,求最少花费多少能从原点到达目标点

 

打的时候总是觉得要枚举起点和终点,或者起点和长度,所以n方是避免不了的。

赛后看题解发现,我们只关心长度,并不关心起点和中间具体是怎样修改的,所以可以二分长度。

#include <bits/stdc++.h>

using namespace std;
const int N=2e5 + 100;
int L[N],U[N],R[N],D[N];
int n,x,y;
bool Che(int len)
{
    int nowx=0,nowy=0,dis;
    for(int i=0;i<=n-len;i++)///枚举起点
    {
        if(i==0)
        {
            if(len)
            {
                nowx=R[n-1]-R[i+len-1]-(L[n-1]-L[i+len-1]);
                nowy=U[n-1]-U[i+len-1]-(D[n-1]-D[i+len-1]);
            }
            else
            {
                nowx=R[n-1]-L[n-1];
                nowy=U[n-1]-D[n-1];
            }
        }
        else
        {
            nowx=R[i-1]-L[i-1]+R[n-1]-R[i+len-1]-(L[n-1]-L[i+len-1]);
            nowy=U[i-1]-D[i-1]+U[n-1]-U[i+len-1]-(D[n-1]-D[i+len-1]);
        }
        dis=abs(nowx-x)+abs(nowy-y);
        if(dis<=len)return 1;
    }
    return 0;
}
int main()
{
    string s;
    while(cin>>n)
    {
        cin>>s;
        cin>>x>>y;
        int dd=abs(x)+abs(y);
        if(dd>n||abs(dd-n)%2)
        {
            printf("-1\n");
            continue;
        }
        L[0]=s[0]=='L';
        R[0]=s[0]=='R';
        U[0]=s[0]=='U';
        D[0]=s[0]=='D';
        for(int i=1;i<n;i++)
        {
            L[i]=L[i-1]+(s[i]=='L');
            R[i]=R[i-1]+(s[i]=='R');
            D[i]=D[i-1]+(s[i]=='D');
            U[i]=U[i-1]+(s[i]=='U');
        }
        int l=0,r=n,mid;
        while(r-l>1)
        {
            mid=(l+r)>>1;
            if(Che(mid))r=mid;
            else l=mid;
        }
        if(Che(l))
            printf("%d\n",l);
        else if(Che(r))
            printf("%d\n",r);
        else
            printf("???\n");
    }
    return 0;
}

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值