Codeforces Round #571 (Div. 2) 解题报告 (A ~ D)

比赛地址:Codeforces Round #571 (Div. 2)

A. Vus the Cossack and a Contest

题目大意:有 \(n\) 个人,你有 \(m\) 支笔和 \(k\) 本笔记本,问可不可以给每人一支笔一本笔记本。

解题思路:签到题,直接判断大小即可。

#include <cstdio>

int n, m, k;

int main() {
    scanf("%d%d%d", &n, &m, &k);
    if ((m >= n) && (k >= n)) printf("Yes");
    else printf("No");
    return 0;
}

C. Vus the Cossack and Strings

题目大意:给你两个 01 串 \(a\)\(b\) ,保证长度 \(len_a > len_b\) 现在在 \(a\) 中找出所有长度为 \(len_b\) 的子串 \(c\) ,定义函数 \(f(x,y) = x,y \mbox{字符不同的位置数}\) ,求所有的 \(f(b,c)\) 的值有多少个为偶数。

解题思路:不妨设 \(b\) 串有 \(m\) 个 1 , \(c\) 串有 \(n\) 个 1 ,且 \(b\)\(c\) 中同为 1 的位置数为 \(k\) 。那么 \(b\)\(c\) 中字符不同的位置数有 \(cnt = m - k + n - k = m + n - 2k\) ,因此当 \(m + n\) 为偶数时, \(cnt\) 为偶数,根据数论知识 \(m + n\) 为偶数的充要条件是 \(m \equiv n\ (mod\;2)\) ,因此我们只需要统计每一个子串中 1 的个数就好了,这是可以在 \(\Theta (n)\) 的时间内完成的。

奇技淫巧:众所周知,取模运算是很慢的,怎么加速这一过程呢,我们可以通过 \(n & 1\) 来代替,如果 \(n & 1 = 1\) ,那么 \(n\;mod\;2 = 1\) ,否则 \(2\;|\;n\) ,我们怎么判断相等呢?这个时候可以用异或运算浪一波,两个数相等时,其异或运算结果为 0 ,否则为 1 。

#include <cstdio>
#include <cstring>

const int MAXN = 1e6 + 5;

int lena, lenb, cnt, tmp, ans;
char a[MAXN], b[MAXN];

int main() {
    scanf("%s%s", a + 1, b + 1);
    lena = strlen(a + 1);
    lenb = strlen(b + 1);
    for (int i = 1; i <= lenb; ++i) {
        if (b[i] == '1')
            ++cnt;
        if (a[i] == '1')
            ++tmp;
    }
    if ((cnt & 1) ^ (tmp & 1) == 0)
        ++ans;
    for (int i = lenb + 1; i <= lena; ++i) {
        if (a[i - lenb] == '1')
            --tmp;
        if (a[i] == '1')
            ++tmp;
        if ((cnt & 1) ^ (tmp & 1) == 0)
            ++ans;
    }
    printf("%d", ans);
    return 0;
}

D. Vus the Cossack and Numbers

题目大意:给你一个长度为 \(n\) 的实数序列 \(a\) ,你可以将其中的每一个元素变成 \(b\) ,其中 \(b = \lfloor a \rfloor\)\(\lceil a \rceil\) ,给出一种方案,使得 \(\sum\limits_{i = 1}^{n} b_i = 0\) ,题目保证有解。

解题思路:我们可以先让每一个 \(b\) 最小化,这样一定会使得 \(\sum\limits_{i = 1}^{n} b_i < 0\) ,然后再一个个调大 \(b\) ,使其变成 \(b + 1\) ,逐渐将总和调成 0 。

值得注意的是:因为 \(a_i\) 是实数,所以有可能出现 \(a_i\) 是整数的情况,在这种情况下,对应的 \(b_i\) 只有一种取值,也就不能调大了。

#include <cstdio>
#include <cmath>

const int MAXN = 1e5 + 5;

int n, cnt;
int b[MAXN];
double a[MAXN];

int main() {
    scanf("%d", &n);
    for (int i = 1; i <= n; ++i) {
        scanf("%lf", &a[i]);
        b[i] = floor(a[i]);
        cnt += b[i];
    }
    cnt *= -1;
    for (int i = 1; i <= cnt; ++i) {
        if (a[i] != b[i]) b[i] += 1;
        else ++cnt;
    }
    for (int i = 1; i <= n; ++i) {
        printf("%d\n", b[i]);
    }
    return 0;
}
posted @ 2019-07-04 11:10  lornd  阅读(256)  评论(0编辑  收藏  举报