Vasya and Robot

题意

一串长度为(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;
}

原文地址:https://www.cnblogs.com/zgglj-com/p/9858755.html