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;
}

posted @ 2018-10-26 21:11  天之道,利而不害  阅读(217)  评论(0编辑  收藏  举报