AtCoder Beginner Contest 147

 

A - Blackjack

AtCoder Beginner Contest 147
#include <bits/stdc++.h>

int main() {
    int a, b, c;
    scanf("%d%d%d", &a, &b, &c);
    a += b + c;
    if (a >= 22)
        puts("bust");
    else 
        puts("win");
    return 0;
}
View Code

 

B - Palindrome-philia

AtCoder Beginner Contest 147
#include <bits/stdc++.h>

int main() {
    static char s[110];
    scanf("%s", s);
    int n = strlen(s);
    int ans = 0;
    for (int i = 0; i < n / 2; i++) {
        if (s[i] != s[n - 1 - i]) ans++;
    }
    printf("%d\n", ans);
    return 0;
}
View Code

 

C - HonestOrUnkind2

暴力枚举每种组合即可

AtCoder Beginner Contest 147
#include <bits/stdc++.h>
#define pii pair<int, int>

const int N = 17;
int n, A[N];
std::vector<std::pii> vec[N];
bool is[N];

int get(int x) {
    int ans = 0;
    while (x) {
        ans++;
        x &= (x - 1);
    }
    return ans;
}

bool check() {
    for (int i = 0; i < n; i++) if (is[i]) {
        for (int j = 1; j <= A[i]; j++) {
            if (vec[i][j].second == 1 && !is[vec[i][j].first]) return false;
            if (vec[i][j].second == 0 && is[vec[i][j].first]) return false;
        }
    }
    return true;
}

int main() {
    scanf("%d", &n);
    for (int i = 0; i < n; i++) {
        scanf("%d", A + i);
        vec[i].resize(A[i] + 1);
        for (int j = 1; j <= A[i]; j++) {
            scanf("%d%d", &vec[i][j].first, &vec[i][j].second);
            vec[i][j].first--;
        }
    }
    int ans = 0;
    for (int i = 0; i < (1 << n); i++) {
        for (int j = 0; j < n; j++) {
            if (i >> j & 1) is[j] = 1;
            else is[j] = 0;
        }
        if (check()) ans = std::max(ans, get(i));
    }
    printf("%d\n", ans);
}
View Code

 

D - Xor Sum 4

按位做即可

AtCoder Beginner Contest 147
#include <bits/stdc++.h>
#define ll long long

const int MOD = 1e9 + 7;
const int N = 3e5 + 7;
int cnt[70][2];
ll A[N];

int main() {
    int n;
    scanf("%d", &n);
    int ans = 0;
    for (int i = 1; i <= n; i++) {
        scanf("%lld", A + i);
        for (int j = 0; j <= 60; j++) {
            int id = A[i] >> j & 1;
            id ^= 1;
            (ans += (1LL << j) % MOD * cnt[j][id] % MOD) %= MOD;
            cnt[j][A[i] >> j & 1]++;
        }
    }
    printf("%d\n", ans);
    return 0;
}
View Code

 

E - Balanced Path

$dp[i][j][k]$ 表示走到 $(i,j)$ 位置,能否出现差为 $k - 6400$ 的走法。

然后就背包,可以用 bitset 优化

AtCoder Beginner Contest 147
#include <bits/stdc++.h>

const int N = 88;
const int M = 6400;
int n, m, A[N][N], B[N][N];
std::bitset<M * 2 + 1> dp[N][N];

int main() {
    scanf("%d%d", &n, &m);
    for (int i = 1; i <= n; i++)
        for (int j = 1; j <= m; j++)
            scanf("%d", A[i] + j);
    for (int i = 1; i <= n; i++)
        for (int j = 1; j <= m; j++)
            scanf("%d", B[i] + j);
    dp[0][1].set(M);
    dp[1][0].set(M);
    for (int i = 1; i <= n; i++)
        for (int j = 1; j <= m; j++) {
            int d = std::abs(A[i][j] - B[i][j]);
            dp[i][j] |= (dp[i - 1][j] << d) | (dp[i - 1][j] >> d);
            dp[i][j] |= (dp[i][j - 1] << d) | (dp[i][j - 1] >> d);
        }
    int ans = 1e9;
    for (int i = 0; i <= 2 * M; i++)
        if (dp[n][m].test(i))
            ans = std::min(ans, std::abs(i - M));
    printf("%d\n", ans);
    return 0;
}
View Code

 

F - Sum Difference

即求能组成多少种 $S$。

当 $D=0$ 时,如果 $X=0$,那么 $S$ 只有一种取值 $0$,否则就有 $n+1$ 种取值,$0, X, 2X, \cdots, nX$。

若 $D<0$,可以把 $X$ 和 $D$ 都乘上 $-1$,这样就只需要考虑 $D>0$ 的情况。

当 $S$ 中有 $k$ 个元素时,$S = kX + I * D$

$0 + 1 + \cdots + (k - 1) \leq I \leq (n - k) + \cdots + (n - 1)$。

相当于一条线段,然后再把这条线段左右端点都加上 $kX / D$ 的值,就变成了一个三元组 $(kX \mod D, l, r)$

对于相同的 $kX \mod D$,线段 $l, r$ 的并集就是答案了。

排序之后扫一遍就行了。

上一篇:ASCII表


下一篇:7.28笔记(第147场周赛前两道)