Div. 2 ,C. Vasya and Robot

这个题目第一眼看并不是一个二分,仔细思考一下,要枚举长度,然后又要枚举起点,这里已经是O(n^2)的复杂度了,还要判断是否满足条件,如果预处理了,是能在O(1)的复杂度解决的。所以枚举长度这边可以用一个二分,这样复杂度就是O(nlogn)了,可以解决这个题目。

如何在O(n)的复杂度判断这个长度满不满足要求呢?

枚举起点就要O(n)了,接下来就是O(1)判断O不OK;预处理到第i个字母时往右往上偏移了几位,那么枚举到一段区间的时候,我们可以将那一段区间的操作全部撤销(反正全改,长度也是len),那么此时的位置移到目标点最少的操作num 就是现在的位置和终点在X轴上的偏移量+Y轴上的偏移量,如果len>num,那么len-num一定要是偶数,这样上下左右才可以抵消。

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
ll n,ex,ey;
const int maxn=2e6+5;
struct X{
	ll r,u;
}f[maxn]; 
bool flag=0;
bool pd(int len){
	for(int i=1;i+len-1<=n;++i){
		ll rr=f[i+len-1].r-f[i-1].r,uu=f[i+len-1].u-f[i-1].u;//区间r和u的偏移量
		ll num=abs(ex-(f[n].r-rr))+abs(ey-(f[n].u-uu));//所需要的最小操作数
		if(len>=num&&(len-num)%2==0){
			flag=1;//说明可以走到终点
			return 1;
		}
	}
	return 0;
}
int main(){
	scanf("%lld",&n);
	getchar();
	f[0].r=0,f[0].u=0;
	char tmp;
	for(int i=1;i<=n;++i){
		scanf("%c",&tmp);//预处理
		if(tmp=='R')	f[i].r=f[i-1].r+1,f[i].u=f[i-1].u;
		if(tmp=='L')	f[i].r=f[i-1].r-1,f[i].u=f[i-1].u;
		if(tmp=='U')	f[i].u=f[i-1].u+1,f[i].r=f[i-1].r;
		if(tmp=='D')	f[i].u=f[i-1].u-1,f[i].r=f[i-1].r;
	}
	getchar();
	scanf("%lld%lld",&ex,&ey);
	if(f[n].r==ex&&f[n].u==ey)	cout<<0<<endl;
	else{
		int le=0,ri=n+1;
		while(ri>le){
			int mid=(le+ri)/2;
			if(pd(mid))	ri=mid;
			else	le=mid+1;
		}
		if(!flag)	cout<<-1<<endl;
		else	cout<<le<<endl;
	}
	return 0;
}

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值