Vasya and Robot - codeforce
题意
一串长度为\(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;
}