Codeforces Round #642 (Div. 3) 补题

Codeforces Round #642 (Div. 3)

题目链接(contest 1353)

1353E:K-periodic Garland

  • 题意:给定一个只有0 1字符的字符串,字符串长度n,数字k。你每次操作都可以令任意一个字符取反(0变为1,1变为0)。字符串需要变为这种状态:相邻两个1字符的位置l, r(l < r),需要满足r - l = k 。问使给定字符串改变为所需字符串至少需要多少次操作。

  • 思路:对于任意的r, l,若有r - l = k,则r与l应对k同余。题意可以理解为:在字符串中,只存在一个整数m,所有满足i % k = m(i为字符串下标)的字符组成一个子序列。除该子序列的一个子段中所有元素为1外,字符串其他位置均为0。求将原字符串修改为这样的字符串最少需要多少次操作。 我们可以先假定将字符串中所有1改变为0,然后遍历m的所有可能取值,寻找需要操作次数最少的“元素全为1的子段”,然后用该操作次数加上所有字符1的个数就得到了答案。

  • E题代码:

#include 
 
using namespace std;
const int maxn = 1e6 + 10;
char str[maxn];
 
int main() {
    int t, n, k, num_one, num_now, num_min;
    scanf("%d", &t);
    while (t--) {
        scanf("%d %d %s", &n, &k, str);
        num_one = 0;
        num_min = 0x3f3f3f3f;
        for (int i = 0; i < n; i++) {
            if (str[i] == '1') {
                num_one++;
            }
        }
        for (int i = 0; i < k; i++) {
            num_now = 0;
            //寻找最小子段和
            for (int j = i; j < n; j += k) {
                if (str[j] == '0')
                    num_now++; //0需要变为1,操作一次
                else
                    num_now--; //1不需要改变,但在now_one中计算过了,需要减去。
                if (num_now > 0) num_now = 0;
                if (num_now < num_min) num_min = num_now;
            }
        }
        num_min += num_one;
        printf("%d\n", num_min);
    }
    return 0;
}

1353F: Decreasing Heights

还没补(逃)。

你可能感兴趣的:(codeforces补题)