AtCoder Beginner Contest 210 (A~E)

比赛链接:Here

A - Cabbages

B - Bouzu Mekuri

C - Colorful Candies

用map维护连续一段区间的不同元素即可。

int main() {
    cin.tie(nullptr)->sync_with_stdio(false);
    int n, k; cin >> n >> k;
    vector<int>a(n + 1);
    map<int, int>mp;
 
    for (int i = 1; i <= n; ++i)cin >> a[i];
    for (int i = 1; i <= k; ++i)mp[a[i]]++;
 
    int ans = mp.size();
 
    for (int i = k + 1; i <= n; ++i) {
        mp[a[i]]++;
        mp[a[i - k]]--;
        if (mp[a[i - k]] == 0) mp.erase(a[i - k]);
        ans = max(ans, (int)mp.size());
    }
 
    cout << ans << "\n";
}

D - National Railway

给一个矩阵,矩阵每一个位置都有值,要求选取两个位置使得: val= 两个位置的值之和 + 两个位置的曼哈顿距离 × 系数 c 最小。


思路:显然不能枚举两个位置,考虑DP,

f(i,j) 表示在从 (1,1)(i,j) 内的元素到 (i,j)的距离加上值的最小值。这个就很好转移了。需要注意的是选取的两个点不一定是左上,右下的关系,所以需要沿着右上左下再做一次。

const int N = 1e3 + 10;
ll a[N][N];

int main() {
    cin.tie(nullptr)->sync_with_stdio(false);
    ll H, W, C;
    cin >> H >> W >> C;
    vector<vector<ll>>dp(H, vector<ll>(W)), a(H, vector<ll>(W));
    for (int i = 0; i < H; ++i)for (int j = 0; j < W; ++j)cin >> a[i][j];
    ll _ = 2, Mi = 1ll << 60;
    while (_--) {
        for (int i = 0; i < H; ++i)
            for (int j = 0; j < W; ++j) {
                ll up = (i - 1 >= 0 ? dp[i - 1][j] : 1ll << 60);
                ll left = (j - 1 >= 0 ? dp[i][j - 1] : 1ll << 60);
                dp[i][j] = min(a[i][j], min(up, left) + C);
                Mi = min(Mi, min(up, left) + C + a[i][j]);
            }
        reverse(a.begin(), a.end());
    }
    cout << Mi << "\n";
}

E - Ring MST

n个顶点,m 种能够花费 c 连接顶点i ii和 i+a 的边,i 可以随便取, 边数无限。问使得图连通最少花费。如果不能连通输出 1


把图连通,花费最小,考虑最小生成树的思想,先选择花费最小的边去连,如果两个顶点在同一集合,就不连。本题 n1e9,不能建边做。但可以用类似的思想,先找出花费最小的边的种类,假设这种边可以连接 ii+a , 然后一直使用这种边去连接顶点,最后无法再连的时候所有点就会被分成gcd(n,a) 个集合,即连接了 ngcd(n,a)条边。继续用花费第二小的边连接顶点,可以发现当不能再连接的时候,所有点被分成gcd(n,a,a)个集合,一直这样做,如果gcd能等于 1 ,就说明已经连通了。

int main() {
    cin.tie(nullptr)->sync_with_stdio(false);
    int n, m;
    cin >> n >> m;

    pair<int, int>p[m + 1];
    for (int i = 1; i <= m; ++i) cin >> p[i].second >> p[i].first;
    sort(p + 1, p + 1 + m);

    ll ans = 0;
    for (int i = 1; i <= m; ++i) {
        int d = __gcd(n, p[i].second);
        ans += 1ll * (n - d) * p[i].first;
        n = d;
    }
    cout << (n == 1 ? ans : -1);
}

F - Coprime Solitaire

不会

posted @   RioTian  阅读(203)  评论(0编辑  收藏  举报
编辑推荐:
· 探究高空视频全景AR技术的实现原理
· 理解Rust引用及其生命周期标识(上)
· 浏览器原生「磁吸」效果!Anchor Positioning 锚点定位神器解析
· 没有源码,如何修改代码逻辑?
· 一个奇形怪状的面试题:Bean中的CHM要不要加volatile?
阅读排行:
· 分享4款.NET开源、免费、实用的商城系统
· Obsidian + DeepSeek:免费 AI 助力你的知识管理,让你的笔记飞起来!
· MongoDB 8.0这个新功能碉堡了,比商业数据库还牛
· 白话解读 Dapr 1.15:你的「微服务管家」又秀新绝活了
· 全程不用写代码,我用AI程序员写了一个飞机大战
历史上的今天:
2020-07-20 signed main 和 int main 的区别
2020-07-20 Codeforces Round #656 (Div. 3)部分题解
点击右上角即可分享
微信分享提示

📖目录