zoukankan      html  css  js  c++  java
  • 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 << "
    ";
    }
    

    D - National Railway

    给一个矩阵,矩阵每一个位置都有值,要求选取两个位置使得: (val=) 两个位置的值之和 (+) 两个位置的曼哈顿距离 ( imes) 系数 (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 << "
    ";
    }
    

    E - Ring MST

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


    把图连通,花费最小,考虑最小生成树的思想,先选择花费最小的边去连,如果两个顶点在同一集合,就不连。本题 (n≤1e9),不能建边做。但可以用类似的思想,先找出花费最小的边的种类,假设这种边可以连接 (i)(i + a) , 然后一直使用这种边去连接顶点,最后无法再连的时候所有点就会被分成(gcd(n, a)) 个集合,即连接了 (n - gcd(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

    不会

    The desire of his soul is the prophecy of his fate
    你灵魂的欲望,是你命运的先知。

  • 相关阅读:
    搭建页面:数据库的增删改查
    阿里云的使用运维安装
    promis:异步编程
    微信开发笔记
    细数那些带打赏功能的平台
    写给自己的TypeScript 入门小纲
    Node.js自学笔记之回调函数
    来简书坚持一个月日更之后
    全选或者单选checkbox的值动态添加到div
    一个前端妹子的悲欢编程之路
  • 原文地址:https://www.cnblogs.com/RioTian/p/15035411.html
Copyright © 2011-2022 走看看