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

比赛链接:Here

A、B题跳过

C - chokudai

题意:

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


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

f[j]=f[j]+f[j1] 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×N 个方格中的K个方格的选择数是 CN2k ,由于 C648=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 @   RioTian  阅读(217)  评论(0编辑  收藏  举报
编辑推荐:
· 探究高空视频全景AR技术的实现原理
· 理解Rust引用及其生命周期标识(上)
· 浏览器原生「磁吸」效果!Anchor Positioning 锚点定位神器解析
· 没有源码,如何修改代码逻辑?
· 一个奇形怪状的面试题:Bean中的CHM要不要加volatile?
阅读排行:
· 分享4款.NET开源、免费、实用的商城系统
· Obsidian + DeepSeek:免费 AI 助力你的知识管理,让你的笔记飞起来!
· MongoDB 8.0这个新功能碉堡了,比商业数据库还牛
· 白话解读 Dapr 1.15:你的「微服务管家」又秀新绝活了
· 全程不用写代码,我用AI程序员写了一个飞机大战
历史上的今天:
2020-07-25 有向无环图
2020-07-25 图的存储
2020-07-25 Codeforces Round #658 (Div. 2)
2020-07-25 POJ 3259 Wormholes(bellman_ford、Floyd、SPFA判断负环)
2020-07-25 C++ string 字符串函数详解
点击右上角即可分享
微信分享提示

📖目录