1. 程式人生 > >【Educational Codeforces Round 53 (Rated for Div. 2)-C. Vasya and Robot】二分

【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)處
( x , y ) , ( L , R , U , D ) 最終他要走到點(x,y)處,現在給出行動路線,有(L,R,U,D)四種走法

每次他可以修改某個區間內的走法,問需要修改的最小區間長度是多少
(區間內可以修改為任意走法,也可以不修改)
n < = 2 1 0 5 n<=2*10^5

做法

( x , y ) 這個資料範圍大概只能想二分,二分長度之後列舉每個點作為區間起點是否能走到(x,y)
c h e c k ( x 1 , y 1 ) check的過程就是先把區間之外的走法走完,得到(x1,y1)
( x 1 , y 1 ) ( x , y ) D 再判斷(x1,y1)與(x,y)的曼哈頓距離D
l e n > D l e n D ) M o d 2 = = 0 ( x , y ) 如果當前區間長度len>D而且(len-D)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;
}