• Codeforces Round #787 (Div. 3)ABCD


    记录一下,感觉写的最好的一次了,前四个思路都很流畅。不过不太会写DFS,D调了很久很久很久 ..,E没什么思路。之后看看题解再做一做。(菜,三月份才开始做,刚到绿名。。
    image

    A. Food for Animals

    签到题

    #include <iostream>
    
    using namespace std;
    
    void solve()
    {
        int a, b, c, x, y;
        cin >> a >> b >> c >> x >> y;
        if(max(x - a, 0) + max(y - b, 0) <= c)  puts("YES");
        else    puts("NO");
        return;
    }
    
    int main()
    {
        int t = 1;
        cin >> t;
        while(t --)
        {
            solve();
        }
        return 0;
    }
    

    B. Make It Increasing

    题意:对任意一个数都能操作任意次数除2,问最少操作多少次,使数组严格递增
    思路:可以从倒数第二个开始往前看,若a[i] >= a[i + 1]就一直除2,直到小于为止;如果发现a[i + 1]已经是0了,说明当前这个数已经无法再变小了,就输出-1。

    #include <iostream>
    
    using namespace std;
    
    const int N = 33;
    int a[N];
    
    void solve()
    {
        int n;
        cin >> n;
        for(int i = 0; i < n; i ++ )
            cin >> a[i];
        int ans = 0;
        bool flag = true;
        for(int i = n - 2; i >= 0; i --)
        {
            if(a[i + 1] == 0)
            {
                flag = false;
                break;
            }
            while(a[i] >= a[i + 1])
            {
                a[i] /= 2;
                ans ++;
            }
        }
        if(flag)    printf("%d\n", ans);
        else    puts("-1");
        return;
    }
    
    int main()
    {
        int t = 1;
        cin >> t;
        while(t --)
        {
            solve();
        }
        return 0;
    }
    

    C. Detective Task

    题意:有n个人进来看画,其中有个人会偷走画,在调查时,每个人会回答0(没看到画)、1(看到了画)、?(忘记了),除了小偷之外,说的都是真话,问:有多少个偷画的嫌疑人?
    思路:找到一个0,下标为t0;找到第一个1,下标为t1。t0一定有嫌疑,如果t0是偷画人,之后的人都不是嫌疑人;如果t0不是偷画人,t0之前的人要被怀疑,t0之后的不用被怀疑;t1一定有嫌疑,作为最后一个看到画的人,t1之前的都不用被怀疑。因此t1到t0之间的都是嫌疑人。
    t0和t1初始化为-1
    还要判断特殊情况,如果字符串中没有1和0,即都是?,那么都是嫌疑人;如果有1无0,那么t1到最后都是嫌疑人;如果有0无1,那么开始到t0都是嫌疑人。

    #include <iostream>
    
    using namespace std;
    
    void solve()
    {
        string s;
        cin >> s;
        int n = s.size();
        int t1 = -1, t0 = -1;
        for(int i = 0; i < n; i ++ )
            if(s[i] == '1') t1 = i;
        for(int i = 0; i < n; i ++ )
            if(s[i] == '0')
            {
                t0 = i;
                break;
            }
        int ans = 0;
        if(t1 == -1 && t0 == -1)    ans = n;
        else if(t1 == -1 && t0 != -1)  ans = t0 + 1;
        else if(t1 != -1 && t0 == -1)   ans = n - t1;
        else if(t1 != -1 && t0 != -1)   ans = t0 - t1 + 1;
        printf("%d\n", ans);
        return;
    }
    
    int main()
    {
        int t = 1;
        cin >> t;
        while(t --)
        {
            solve();
        }
        return 0;
    }
    

    D - Vertical Paths

    题意:给定一棵树,求最少的路径数,从上往下能够不重复的包括所有的点
    思路:根据给出的每个点的父节点,建图,从父节点到子节点连一条边。从根节点开始dfs遍历,遍历过程中记录路径数。

    #include <iostream>
    #include <cstring>
    #include <algorithm>
    #include <vector>
    
    using namespace std;
    
    const int N = 200010;
    int h[N], e[N], ne[N], idx;
    int p[N];
    bool st[N];
    vector<int> path[N];
    
    void add(int a, int b)
    {
        e[idx] = b, ne[idx] = h[a], h[a] = idx ++ ;
    }
    
    void dfs(int u, int father, int &cnt)
    {
        for(int i = h[u]; ~i; i = ne[i])
        {
            int j = e[i];
    
            if(!st[u])
            { 
                path[cnt].push_back(j);
                st[u] = true;
            }
            else path[++ cnt].push_back(j);
    
            dfs(j, u, cnt);
        }
    }
    
    void solve()
    {
        memset(st, 0, sizeof st);
        memset(h, -1, sizeof h);
        
        int n, root;
        cin >> n;
        for(int i = 1; i <= n; i ++ )   cin >> p[i];
        
        for(int i = 1; i <= n; i ++ )
            if(p[i] != i)
                add(p[i], i);
            else    root = i;
            
    
        int cnt = 1;
        path[cnt].push_back(root);
        dfs(root, -1, cnt);
        printf("%d\n", cnt);
        for(int i = 1; i <= cnt; i ++ )
        {
            printf("%d\n", path[i].size());
            for(auto v : path[i])
                printf("%d ", v);
            path[i].clear();
            puts("");
        }
        puts("");
        return;
    }
    
    int main()
    {
        int t = 1;
        cin >> t;
        while(t --)
        {
            solve();
        }
        return 0;
    }
    
  • 相关阅读:
    反转句子
    算法和数据操作-查找和排序
    算法和数据操作-递归和循环
    数据结构-树
    数据结构-栈和队列
    Spring的循环依赖
    关于mybatis的执行流程和源码
    JVM之了解JVM的结构和加载机制
    多线程之(线程管理)
    Spring容器创建过程
  • 原文地址:https://www.cnblogs.com/Hfolsvh/p/16227074.html
Copyright © 2020-2023  润新知