-
题目传送:
http://codeforces.com/contest/1073/problem/C
-
题意:
给出一段错误路径,现要求修改路径,使得能够成功到达目标坐标。求最小修改量。
-
思路:
若最终能使改动后到达目标坐标(tarx,tary),设改动区间长度len,记删除len内容后的位置坐标为(nowx,nowy),计算出(nowx,nowy)与目标坐标(tarx,tary)的曼哈顿距离dis。由于,行走时可来回反复,只需满足条件:修改的区间长度len与dis的奇偶性一致,且len大于等于dis即可满足。题意要求最小改动区间长度,可以用二分法查找符合条件的len的情况。
-
代码:
#include <iostream>
#include <string>
#define MAX 200005
using namespace std;
int x[MAX];
int y[MAX];
bool judge(int n,int len,int tarx,int tary)
{
for (int i=1;i<=n-len+1;i++)
{
int nowx=x[i-1]+x[n]-x[i+len-1]; //求出删去len段后的位置
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()
{
int n;
cin>>n;
string str;
cin>>str;
int tarx,tary;
cin>>tarx>>tary;
for (int i=1;i<=n;i++)
{
if (str[i-1]=='R')
x[i]=1;
else if (str[i-1]=='L')
x[i]=-1;
else if (str[i-1]=='U')
y[i]=1;
else if (str[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 sid=0,eid=n;
int ans=-1,halfid;
while(sid<=eid) //二分
{
halfid=(sid+eid)/2;
if(judge(n,halfid,tarx,tary))
{
ans=halfid;
eid=halfid-1;
}
else
{
sid=halfid+1;
}
}
cout<<ans<<endl;
}