Educational Codeforces Round 53 (Rated for Div. 2) C. Vasya and Robot(二分或者尺取)

时间:2023-03-09 15:52:45
Educational Codeforces Round 53 (Rated for Div. 2)  C. Vasya and Robot(二分或者尺取)

题目哦

题意:给出一个序列,序列有四个字母组成,U:y+1,D:y-1 , L:x-1 , R:x+1;   这是规则 。 给出(x,y) 问可不可以经过最小的变化这个序列可以由(0,0) 变到(x,y)

注意!!!!是可以变任意序列的!不是只有y变y , x变x ,比赛看错题意导致没A ,

分析:这需要借助前置和与后缀和 , 这样的话我就可以知道[L , R] 这个区间需要变化什么 , 没错你可以理解为题目的范围n变为[L , R] , x变为x-xl[L+1]-xr[R+1] ,y同理; 这样我们就可以运用尺取法,不断的枚举区间就好了。我用的是尺取法 , 许多人用的是二分 ,不过思想是一样的,这个一样贴出代码

需要理解下判断条件问题(结合代码):很容易就知道n<abs(x)+abs(y) 这样是不行的, 还有就是n与(abs(x)+abs(y))的奇偶性也必须一样 , 因为不可能有偶数次运算后变奇数(建议模拟一遍);既然前面说到是理解为题目的范围n变为[L , R] , x变为x-xl[L+1]-xr[R+1] ,y同理 , 那在二分或者尺取的时候的判断也是如此

尺取:

#include<bits/stdc++.h>
using namespace std ;
const int maxn = *1e5+;
#define ll long long
ll xl[maxn],xr[maxn],yl[maxn],yr[maxn];
char s[maxn];
int main( )
{
int n,x,y; scanf("%d",&n);
getchar();
scanf("%s",s+);
scanf("%d%d",&x,&y);
int NOWX=,NOWY=;
int MIN=n;
for(int i= ; i<=n ; i++)
{
xl[i]=xl[i-];
yl[i]=yl[i-];
if(s[i]=='U')
{
yl[i]++;
NOWY++;
}
if(s[i]=='D')
{
yl[i]--;
NOWY--;
}
if(s[i]=='L')
{
xl[i]--;
NOWX--;
}
if(s[i]=='R')
{
xl[i]++;
NOWX++;
}
} if(NOWX==x&&NOWY==y)
{
puts("");
return ;
}
if(abs(x)+abs(y)>n)
{
puts("-1");
return ;
}
if((n-(abs(x)+abs(y)))%!=)
{
puts("-1");
return ;
}
for(int i=n ; i>= ; i--)
{
xr[i]=xr[i+];
yr[i]=yr[i+];
if(s[i]=='U')
{
yr[i]++;
}
if(s[i]=='D')
{
yr[i]--;
}
if(s[i]=='L')
{
xr[i]--;
}
if(s[i]=='R')
{
xr[i]++;
}
}
int head,tail;
head=;
tail=;
while()
{ int X=xr[tail+]+xl[head-];
int Y=yr[tail+]+yl[head-];
int D=tail-head+;
// printf("%d %d (%d %d)\n",head,tail,X,Y);
if((D>=abs(x-X)+abs(y-Y))&&(D-abs(X-x)-abs(Y-y))%==)
{
head++;
MIN=min(MIN,D);
}
else
tail++;
if(tail>n)
break; }
printf("%d\n",MIN);
}

二分:

#include<bits/stdc++.h>
using namespace std;
const int N=2e5+;
int xl[N],yl[N],xr[N],yr[N];
int n;
int x,y;
int check(int mid)
{
int l=;
for(int r=mid;r<n;r++)
{
int tx=xl[l-]+xr[r+];
int ty=yl[l-]+yr[r+];
int rx=abs(x-tx);
int ry=abs(y-ty);
if(mid>=rx+ry && (mid-(rx+ry))%==)
return ;
l++;
}
return ;
}
int main()
{
cin>>n;
string s;
cin>>s;
s='@'+s;
n++;
for(int i=;i<n;i++)
{
xl[i]=xl[i-],
yl[i]=yl[i-];
if(s[i]=='U')
{
yl[i]++;
}
if(s[i]=='D')
{
yl[i]--;
}
if(s[i]=='L')
{
xl[i]--;
}
if(s[i]=='R')
{
xl[i]++;
}
}
for(int i=n-;i>;i--)
{
xr[i]=xr[i+],
yr[i]=yr[i+];
if(s[i]=='U')
{
yr[i]++;
}
if(s[i]=='D')
{
yr[i]--;
}
if(s[i]=='L')
{
xr[i]--;
}
if(s[i]=='R')
{
xr[i]++;
}
}
cin>>x>>y;
int l=-,h=n;
while(h-l>)
{
int mid=(h+l)/;
if(check(mid))
h=mid;
else l=mid;
}
if(h==n)cout<<"-1";
else
cout<<h;
}