【链接】 我是链接,点我呀:)
【题意】
【题解】
如果|x|+|y|>n 显然。从(0,0)根本就没法到(x,y) 但|x|+|y|<=n还不一定就能到达(x,y) 注意到,你每走一步路 |x|+|y|的奇偶性会发改变奇变偶,偶变奇。 因此,如果|x|+|y|的奇偶性和n不一样的话。 显然也是没法走到(x,y)的 可以这么理解,先走|x|+|y|步到达(x,y) 然后n-(|x|+|y|)显然是一个偶数(奇偶性一样的话,相减为偶数) 因此,它肯定又能走回来。 ———————————————————————— 这两种情况去除掉之后。就一定有解了。 怎么找到这个解? 题中要求的值,转化一下。 其实就是说有一段区间[l..r] 你可以将s[l..r]中的字符任意改变。 然后使得s[1..n]操作之后,能从原点走到(x,y) 请你求出r-l+1的最小值,也即区间长度的最小值。 会发现。 如果长度为x的区间可以满足要求的话。 那么长度为x+1的区间肯定也可以满足要求。 因此可以二分。 ———————————————————— 我们二分最后的长度len 然后枚举这个区间的起点i 设s[1..i-1]和s[i+len-1+1..n]这两段操作过后,能从(0,0)走到(x0,y0) (先走前面和后面这两段不影响 那么我们接下来要考虑的问题就是,s[i..i+len-1]这一段操作序列能否让机器人从(x0,y0)走到(x,y) 设temp1 = abs(x0-x)+abs(y0-y) 如果temp1<=len 那么就一定有解。 因为我们可以再花费temp1步从(x0,y0)走到(x,y) 设temp2 = i-1 + n-i; 剩下rest=n-temp1-temp2步要走。 我们总能从这temp1+temp2中提出来|x|+|y|步是从(0,0)不绕弯路直接走到(x,y)的。 这个|x|+|y|<=temp1+temp2 而我们现在的位置又回到了(x,y) 这就说明temp1+temp2-(|x|+|y|)为偶数。 也即temp1+temp2的奇偶性和|x|+|y|相同。 那么根据题解一开始的分析|x|+|y|的奇偶性和n相同(不然无解); 因此temp1+temp2的奇偶性和n也相同。 那么rest的值就肯定为一个偶数了.(两个奇偶性相同的数字相减,肯定是一个偶数). 因此我们总能再次回到(x,y)这个位置的。也即满足要求。 那么返回true.【代码】
#include <bits/stdc++.h>
#define ll long long
#define rep1(i,a,b) for (int i = a;i <= b;i++)
#define rep2(i,a,b) for (int i = a;i >= b;i--)
using namespace std;
const int N = 2e5;
int n;
ll x,y;
ll px[N+10],py[N+10];
char s[N+10];
bool ok(int len){
rep1(i,1,n){
if (i+len-1>n) return 0;
ll x0 = px[i-1]-px[0],y0=py[i-1]-py[0];
x0+=px[n]-px[i+len-1];y0+=py[n]-py[i+len-1];
ll temp = abs(x-x0)+abs(y-y0);
if (temp<=len) return 1;
}
return 0;
}
int main(){
#ifdef ccy
freopen("rush.txt","r",stdin);
#endif
scanf("%d",&n);
scanf("%s",s+1);
scanf("%lld%lld",&x,&y);
ll temp = abs(x)+abs(y);
if (temp>n || ( (temp&1) != (n&1) ) ){
puts("-1");
return 0;
}
rep1(i,1,n){
px[i] = px[i-1];py[i] = py[i-1];
if (s[i]=='L') px[i]--;
if (s[i]=='R') px[i]++;
if (s[i]=='U') py[i]++;
if (s[i]=='D') py[i]--;
}
int l = 0,r = n,temp1 = -1;
while (l <= r){
int mid = (l+r)>>1;
if (ok(mid)){
temp1 = mid;
r = mid-1;
}else{
l = mid+1;
}
}
printf("%d
",temp1);
return 0;
}