zoukankan      html  css  js  c++  java
  • Educational Codeforces Round 84 (CDE)

    C. Game with Chips

    题目: https://codeforces.com/contest/1327/problem/C

    题解

    先将(k)(chip)移到同一个点:左上角。然后,走(S)形遍历整个图就行了
    最多操作次数: ((n - 1) + (m - 1) + (n * m - 1)) (<) (2 * n * m)
    (秒啊,没想到将它们移到同一点)

    D. Infinite Path

    题目:https://codeforces.com/contest/1327/problem/D

    题解

    官方题解的描述实在蛋疼
    推荐这位博主:https://blog.csdn.net/weixin_44178736/article/details/105180870?>

    首先,一般都能观察到满足定义的(Infinite) (Path)构成了一个环,既存在(p[p[···p[i]]] = i)。实际上,一个排列 (p) 按照((i, p[i]))建边后形成的图恰好是由这样的环((Infinite) (Path))组成。模拟一下(p^k)的操作,发现(p^k)可以看做是每个点在环上不停的移动(k)次(动笔画一下比较好理解)。
    然后,枚举(k)。记环的长度为(m),假设 (m) (\%) (k) (!= 0),那么对于任意一点,不停的移动,最终都会经过所有的点,等价于(k = 1),所以只需要枚举(m)的因数,将其作为(k)就行。实际上,有点类似离散数学中的:等价类。将原来的1个环划分为现在的(k)个环。
    最后,检查这(k)个环中所有的点的颜色是否相同就行,满足的话更新答案。

    复杂度的证明请看讨论:https://codeforces.com/blog/entry/75147

    
    void Solve() {
        int n;
        scanf("%d", &n);
    
        vector<int> p(n + 1), color(n + 1), use(n + 1, 0);
        myfor(i, 0, n) scanf("%d", &p[i + 1]);
        myfor(i, 0, n) scanf("%d", &color[i + 1]);
    
        int ans = INF;
        myfor(i, 0, n) if (!use[p[i + 1]]) {
            int v = p[i + 1];
    
            vector<int> cycle;
            while(!use[v]) {
                use[v] = 1;
                cycle.push_back(v);
                v = p[v];
            }
            
            myfor(step, 1, cycle.size() + 1) if (cycle.size() % step == 0) {    // 枚举 k
                myfor(j, 0, step) {        // 枚举起点
                    bool flag2 = true;
    
                    //检查环中的每个点颜色是否相同
                    for (int k = j; k  + step < cycle.size(); k += step) if (color[cycle[k]] != color[cycle[k + step]]) {      
                        flag2 = false;
                        break;
                    }
    
                    if (flag2) {
                        ans = min(ans, step);
                        break;
                    }
                }
    
            }
        }
        
        cout << ans << endl;
        return;
    }
    
    

    E. Count The Blocks

    题目:https://codeforces.com/contest/1327/problem/E

    题解

    ①长度为(len)的块在中间

    • (ans_{len} = (n - len - 1) * 10 * 9 * 9 * 10^{n - len - 2})

    ②长度为(len)的块在两端

    • (ans_{len} = 2 * 10 * 9 * 10 ^{n - len - 1})

    纯粹就是组合数学问题,类似于有m个座位,n个人坐在一起且相邻,既任意两个人之间没有空位,问有多少种方案。本题只是多了些限制条件

    int n;
    long long d[MAXN];
    
    void Inite() {
        d[0] = 1;
        for (int i = 1; i < MAXN; ++i) d[i] = d[i - 1] * 10 % mod;
    }
    
    int main() {
    
        cin >> n;
    
        Inite();
    
        for (int i = 1; i <= n; ++i) {
            long long ans = 0;
            if (n - i >= 2) ans = ((n - i - 1) * 81 * d[n - i - 1] % mod + ans) % mod;
            if (n - i >= 1) ans = (18 * d[n - i] + ans) % mod;
            else ans = (10 + ans) % mod;
            cout << ans << " ";
        }
    
        cout << endl;
        return 0;
    }
    
    
  • 相关阅读:
    【XXE学习】XML外部实体注入
    记一次解密wireshark抓取的冰蝎通信流量
    weblogicSSRF漏洞复现
    解决docker删除加载失败的镜像报错
    【vulapps】Sturcts2 S2-037RCE漏洞复现
    【XSS-labs】level 16-20
    解决docker-compose下载过慢
    【XSS-labs】Level 11-15
    【XSS-labs】level 6-10
    [PHP]用PHP自己写一个基于zoomeye的api(偷懒必备quq)
  • 原文地址:https://www.cnblogs.com/zgglj-com/p/12612097.html
Copyright © 2011-2022 走看看