AtCoder Beginner Contest 211 (C ~ E) 个人题解

比赛链接:Here

A、B题跳过

C - chokudai

题意:

给出一个字符串,问有多少个字串能构成 chokudai


这道题算是一个简单DP,只要计算某个位置对构成 chokudai 的贡献值即可

\(f[j] = f[j] + f[j - 1]\ if\ s[i] == t[j]\)

\(f[0] = 1\)

const int mod = 1e9 + 7;
ll f[10] = {1};
int main() {
    cin.tie(nullptr)->sync_with_stdio(false);
    string s, t = " chokudai";
    cin >> s;
    int n = s.length();
    for (int i = 0; i < n; ++i)
        for (int j = 1; j <= 8; ++j)
            if (s[i] == t[j]) f[j] = (f[j] + f[j - 1]) % mod;
    cout << f[8] % mod;
}

D - Number of Shortest paths

题意:

高桥王国有 \(n\) 个城市和 \(m\) 个双向道路

请问有多少条最短路径能从城市 \(1\) 走到城市 \(n\)


简单跑一下BFS,同时维护各个城市到城市\(1\) 的最短情况,用DP维护路径数

const int N = 2e5 + 10;
const int mod = 1e9 + 7;
vector<int>e[N];
int dp[N], dist[N];
int main() {
    cin.tie(nullptr)->sync_with_stdio(false);
    memset(dist, -1, sizeof(dist));
    int n, m;
    cin >> n >> m;
    for (int i = 1, a, b; i <= m; ++i) {
        cin >> a >> b;
        e[a].push_back(b);
        e[b].push_back(a);
    }
    queue<int>q;
    dist[1] = 0, dp[1] = 1, q.push(1);
    while (q.size()) {
        int u = q.front(); q.pop();
        for (int v : e[u]) {
            if (dist[v] == -1) {
                dp[v] = dp[u];
                dist[v] = dist[u] + 1;
                q.push(v);
            } else if (dist[u] + 1 == dist[v]) dp[v] = (dp[v] + dp[u]) % mod;
        }
    }
    cout << dp[n];
}

E - Red Polyomino


\(N\times N\) 个方格中的K个方格的选择数是 \(C_{N^2}^k\) ,由于 \(C_64^8 = 4426165368 > 4e9\) ,因此直接暴力是不可能的了。

但是,由于红色方块相互连接,我们可以预测满足条件的组合数量很少。

所以可以跑枚举红色方块连接模式的 DFS(深度优先搜索)就足够了。

using ull = unsigned long long;
int n, k, ans;
char s[10][10];
set<ull>mp;
ull S;

bool check(int x, int y) {
    if (s[x][y] == '#' || (S & 1ull << (x * n + y))) return false;
    if (x > 0 and (S & 1ull << ((x - 1) * n + y))) return true;
    if (x < n - 1 and (S & 1ull << ((x + 1) * n + y))) return true;
    if (y > 0 and (S & 1ull << (x * n + y - 1))) return true;
    if (y < n - 1 and (S & 1ull << (x * n + y + 1))) return true;
    return false;
}

void dfs(int d) {
    if (mp.find(S) != mp.end())return ;
    mp.insert(S);
    if (d == k) {ans++; return ;}
    for (int i = 0; i < n; ++i) for (int j = 0; j < n; ++j) {
            if (check(i, j)) {
                S ^= (1ull << (i * n + j));
                dfs(d + 1);
                S ^= (1ull << (i * n + j));
            }
        }
}

int main() {
    //cin.tie(nullptr)->sync_with_stdio(false); // 需注释,cin 与 scanf 冲突
    cin >> n >> k;
    for (int i = 0; i < n; ++i)  scanf("%s", s[i]);
    for (int i = 0; i < n; ++i) for (int j = 0; j < n; ++j) {
            if (s[i][j] != '#') {
                S ^= (1ull << (i * n + j));
                dfs(1);
                S ^= (1ull << (i * n + j));
            }
        }
    cout << ans << "\n";
}
posted @ 2021-07-25 16:36  RioTian  阅读(201)  评论(0编辑  收藏  举报