我是靠谱客的博主 喜悦楼房,这篇文章主要介绍cf 1073c 二分 思维,现在分享给大家,希望可以做个参考。

题意:给定一个长为n的串,代表机器人的行走方式,要求机器人到达(x,y)点

  将原串的子串修改,求最小的子串的长度

 

思路:

很容易知道如何到达x,y点    假设 res= abs(x)+abs(y);那么 n>=res && (n-res)%2==0

那么如何寻找一个子串呢?

二分枚举长度len,然后枚举所有长度为Len的子串看看有没有可能满足

   枚举子串已经用O(n)的复杂度了

    判断的条件就是剩余到达(nx,ny) 用长度为Len的子串是否能到(nx-x,ny-y)

   这样处理的话,处理前缀 就可以O(1)求Nx,ny了  

  总时间 n*logn

 

#include<bits/stdc++.h>
using namespace std;
#define ll long long
#define pb push_back
#define mp make_pair
#define fi first
#define se second
#define all(v) v.begin(),v.end()
#define pii pair<int,int>
const int N
=2e5+4;
const ll mod = 2e9+7;
const int INF = 1e9+3;
const ll LINF = 1e18+3;
int n; ll x,y;
int R[N],U[N];
char s[N];
bool can(int len){
for(int i=1;i<=n-len+1;++i){
int nx,ny;
//[i,i+len-1]
nx = R[i-1] + R[n]-R[i+len-1];
ny = U[i-1] + U[n]-U[i+len-1];
int need = abs(x-nx)+abs(y-ny);
if(len>=need && (len-need)%2==0)return true;
}
return false;
}
int main(){
cin>>n;
scanf("%s",s+1);
cin>>x>>y;
for(int i=1;i<=n;++i){
R[i]=R[i-1];U[i]=U[i-1];
if(s[i]=='R')R[i]+=1;
if(s[i]=='L')R[i]+=-1;
if(s[i]=='U')U[i]+=1;
if(s[i]=='D')U[i]+=-1;
}
int res= abs(x)+abs(y);
if(n>=res && (n-res)%2==0){
int l=0,r= n;
int ans = n;
while(l<=r){
int mid =(l+r)/2;
if(can(mid)){
r = mid-1;
ans = min(ans,mid);
}
else {
l= mid+1;
}
}
cout<<ans<<endl;
}
else {
cout<<-1<<endl;
}
return 0;
}

 

转载于:https://www.cnblogs.com/wjhstudy/p/9856171.html

最后

以上就是喜悦楼房最近收集整理的关于cf 1073c 二分 思维的全部内容,更多相关cf内容请搜索靠谱客的其他文章。

本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
点赞(82)

评论列表共有 0 条评论

立即
投稿
返回
顶部