传送门:http://codeforces.com/problemset/problem/1073/C
二分专题有两个作业,上一个子段最大平均值刚刚弄个大概,现在再搞搞这题吧
题目大意:就是给你一组字符串,按照这个字符串进行操作机器人可以走到一个地点,问你如何修改这个字符串使得修改的区间最小,让机器人走到给定的地点。
在这不得不感慨一下SYF大佬真的强,代码打的贼快,这题是利用曼哈顿距离
昨晚难道因为没想通本题的判断条件本题失眠了??
今天早晨自己有推了一下,瞬间感觉思路清晰。
题解:
如果按照给定的字符串来走的话会到达一个点,但是你需要走到题目给定的点,那么你就需要修改题目中所给的字符串使得机器人可以走到要求到达的点,但是题目还要求找到最小的修改长度,为了不超时,那么我就可以用二分查找来找到我需要改动的最小的区间长度。如何判断这个长度满足最小距离呢?我们可以从字符串的开头不断的平移最小长度个距离,找到当前相对于起点的偏移量,找到当前的位置和需要走到的位置求解他们的曼哈顿距离,因为在哪个区间中我可以任意修改机器人的方向,也就是说机器人可以来回往复的走,但是如果能够走到想要到达的距离,那么我就满足修改区间的长度大于等于他们的曼哈顿距离,并且他们的坐标要同奇偶,例如我在(-1,0)需要走到(2,0)那显然不能走到。
代码:
#include<iostream>
#include<cstring>
#include<algorithm>
#include<cmath>
using namespace std;
string s;
int tarx,tary;
int n;
int x[200005],y[200005];
bool Is_ok(int len)
{
for(int i=1;i<=n-len+1;i++)
{
int nowx=x[i-1]+x[n]-x[i+len-1];
int nowy=y[i-1]+y[n]-y[i+len-1];
int dis=abs(nowx-tarx)+abs(nowy-tary);
if((len-dis)%2==0&&len>=dis) return true;
}
return false;
}
int main()
{
cin>>n;
cin>>s;
cin>>tarx>>tary;
for(int i=1;i<=n;i++)
{
if(s[i-1]=='R')
{
x[i]=1;
}
else if(s[i-1]=='U')
{
y[i]=1;
}
else if(s[i-1]=='L')
{
x[i]=-1;
}
else if(s[i-1]=='D')
{
y[i]==1;
}
}
for(int i=1;i<=n;i++)
{
x[i]=x[i]+x[i-1];
y[i]=y[i]+y[i-1];
}
int left=0,right=n;
int mid;
int ans=-1;
while(left<=right)
{
mid=(left+right)/2;
if(Is_ok(mid)){
ans=mid;
right=mid-1;
}
else left=mid+1;
}
cout<<ans<<endl;
return 0;
}