题意
一串长度为(n),且只包含(R,L,U,D)这四种字符的字符串。
- (R (x + 1,y))
- (L(x - 1,y))
- (U(x, y + 1))
- (D(x, y - 1))
已知机器人现在的位置是((0,0)),机器人要到的位置是((x_0,y_0))。所以现在可能需要修改某些位置的字符,在被修改的那些位置中,最左端记为(minId),最右端记为(maxId),问所有修改方案中最小的((maxId - minId))的方案。
题解
(O(n))枚举(minId),(O(logn))枚举(maxId)。等价的意思就是枚举答案
int l = 1, r = n + 1;
int ans = -1;
// 注意r的取值 !!!
while(l < r) {
int mid = (l + r) >> 1;
if (check(mid)) {
ans = mid;
r = mid;
}
else l = mid + 1;
}
代码
const int N = 200005;
char s[N];
int n, x, y;
int sx[N], sy[N];
bool check(int len) {
Rep(i, 1, n) {
int l = i, r = i + len - 1;
if (r > n) break;
int tx = sx[l - 1] + sx[n] - sx[r];
int ty = sy[l - 1] + sy[n] - sy[r];
int tt = abs(x - tx) + abs(y - ty);
if (len < tt) continue;
// 如果多了偶数个可以修改的位置
if ((len - tt) % 2 == 0) {
return true;
}
}
return false;
}
int main()
{
sc(n);
scanf("%s", s + 1);
sc(x), sc(y);
Rep(i, 1, n) {
sx[i] = sx[i - 1];
sy[i] = sy[i - 1];
if ((s[i] == 'R') || (s[i] == 'L')) sx[i] = sx[i - 1] + (s[i] == 'R' ? 1 : -1);
if ((s[i] == 'U') || (s[i] == 'D')) sy[i] = sy[i - 1] + (s[i] == 'U' ? 1 : -1);
}
if ((sx[n] == x) && (sy[n] == y)) {
puts("0");
return 0;
}
int l = 1, r = n + 1;
int ans = -1;
while(l < r) {
int mid = (l + r) >> 1;
if (check(mid)) {
ans = mid;
r = mid;
}
else l = mid + 1;
}
cout << ans << endl;
return 0;
}