[AtCoder] F - More Holidays

 

 

Incorrect solution: greedily find out how many consecutive S we can convert to all o. Then for the remaining replace operations, try each starting position in S.

Counter example: S = xooox, M = 2, K = 2. The incorrect solution will get oooooxooox, then run out of replacements, so it outputs 5. The correct answer is xoooooooox with length 8.

Correct solution:

1. the answer must start from an index in [0, N - 1]. If not, say if we start with index i > N - 1, then we can always achieve the same by starting with index i - N. 

2. for each possible starting index i in [0, N - 1], binary search on the length of the longest consecutive o starting from index i:

  • Search range: [0, N * M - start]
  • given start index i and a total length, find out the number of replacements needed to achieve this length
  • shrink the search range by half depending on the above check

3. take the max from step 2. 

 

 

    static void solve(int testCnt) {
        for (int testNumber = 0; testNumber < testCnt; testNumber++) {
            int n = in.nextInt();
            long m = in.nextLong();
            long k = in.nextLong();
            char[] s = in.next().toCharArray();
            int[] ps = new int[n];
            ps[0] = s[0] == 'x' ? 1: 0;
            for(int i = 1; i < n; i++) {
                ps[i] = ps[i - 1];
                if(s[i] == 'x') {
                    ps[i]++;
                }
            }
            long ans = 0;
            for(int start = 0; start < n; start++) {
                ans = max(ans, compute(start, n, m, k, ps));
            }
            out.println(ans);
        }
        out.close();
    }

    static long compute(int start, int n, long m, long k, int[] ps) {
        long l = 0, r = m * n - start;
        while(l < r - 1) {
            long mid = l + (r - l) / 2;
            boolean f = helper(start, n, k, ps, mid);
            if(f) {
                l = mid;
            }
            else {
                r = mid - 1;
            }
        }
        return helper(start, n, k, ps, r) ? r : l;
    }

    static boolean helper(int start, int n, long k, int[] ps, long len) {
        if(len <= n - start) {
            int end = (int)(start + len - 1);
            if(ps[end] - (start > 0 ? ps[start - 1] : 0) <= k) {
               return true;
            }
            else {
                return false;
            }
        }
        else {
            long whole = (len - (n - start)) / n;
            long cost = whole * ps[n - 1] + ps[n - 1] - (start > 0 ? ps[start - 1] : 0);
            int end = (int)((len - whole * n - (n - start)) - 1);
            cost += end >= 0 ? ps[end] : 0;
            if(cost <= k) {
                return true;
            }
            else {
                return false;
            }
        }
    }

 

posted @ 2023-09-14 05:14  Review->Improve  阅读(6)  评论(0编辑  收藏  举报