• Codeforces Round #417 (Div. 2)


    A. Sagheer and Crossroads 枚举

    #include <bits/stdc++.h>
    
    using namespace std;
    typedef long long int LL;
    const int MAXN = 100005;
    int n;
    int a[4][4];
    int main()
    {
        int flag = 0;
        for(int i = 0; i < 4; i++) {
            for(int j = 0; j < 4; j++) scanf("%d", &a[i][j]);
            if(a[i][3] && (a[i][1] || a[i][2] || a[i][0])) flag = 1;
        }
        if(a[0][3] && (a[3][2] || a[2][1] || a[1][0])) flag = 1;
        if(a[1][3] && (a[0][2] || a[3][1] || a[2][0])) flag = 1;
        if(a[2][3] && (a[1][2] || a[0][1] || a[3][0])) flag = 1;
        if(a[3][3] && (a[2][2] || a[1][1] || a[0][0])) flag = 1;
        if(flag) printf("YES
    ");
        else printf("NO
    ");
        return 0;
    }
    View Code

    B. Sagheer, the Hausmeister 暴搜

    B题的意思大概是,有个人要从左下角的楼梯口开始走,把整栋楼的灯关闭需要最小的步数。

    他可以从左边的楼梯->关闭整层的灯->返回左边的楼梯

    也可以从左边的楼梯->关闭整层的灯->到达右边的楼梯

    同样可以讨论右边的楼梯

    当然如果整层楼没有灯可以关闭,他可以直接上一层

    如果整栋楼没有灯可以关闭,他就可以结束了

    #include <bits/stdc++.h>
    
    using namespace std;
    typedef long long int LL;
    const int MAXN = 100005;
    char s[20][105];
    int star = 0, ans = MAXN;
    int num[20], n, m;
    void dfs(int left, int i, int step, int gg) {
        if(step > ans || i < 0) return;
        if(num[i]) {
            if(left) {
                int now = 0;
                for(int j = 1; j <= m; j++) {
                    if(s[i][j] == '1') now++;
                    if(now == num[i]) {
                        gg += now;
                        if(i == 0 || gg == star) {
                            ans = min(ans, step + j);
                            return;
                        }else {
                            dfs(left, i-1, step + j*2 + 1, gg);
                            dfs(left^1, i-1, step + m + 2, gg);
                        }
                        break;
                    }
                }
            }else {
                int now = 0;
                for(int j = 1; j <= m; j++) {
                    if(s[i][m+1-j] == '1') now++;
                    if(now == num[i]) {
                        gg += now;
                         //printf("%d %d %d
    ", left, i, j);
                        if(i == 0 || gg == star) {
                            ans = min(ans, step + j);
                            return;
                        }else {
                            dfs(left^1, i-1, step + m + 2, gg);
                            dfs(left, i-1, step + j*2 + 1, gg);
                        }
                        break;
                    }
                }
            }
        }else return dfs(left, i-1, step+1, gg);
    
    }
    int main() {
        scanf("%d%d", &n, &m);
        for(int i = 0; i < n; i++) scanf("%s", s[i]);
        for(int i = 0; i < n; i++) {
            num[i] = 0;
            for(int j = 0; j < m + 2; j++) {
                if(s[i][j] == '1') num[i]++, star++;
            }
        }
        if(star == 0) return 0*printf("0
    ");
        dfs(1, n-1, 0, 0);
        printf("%d
    ", ans);
        return 0;
    }
    View Code

    C. Sagheer and Nubian Market 二分+排序

    C的题意大概是,有个要要购买商品,他购买商品的价格与商品的价格和他购买物品的数量有关。

    如果这个物品起初的下标是xi,价格是a_xi, 同时他总共购买k个物品的话,这个物品的价格是 a_xi + k*xi

    问你购买商品不超过S元,最多能买几个物品,最少花费多少钱

    二分物品的数量,然后更新每个物品的价格, 排序

    #include <bits/stdc++.h>
    
    using namespace std;
    typedef long long int LL;
    
    const int MAXN = 100005;
    int a[MAXN], n, S;
    LL s[MAXN];
    LL slove(int mid) {
        for(int i = 0; i < n; i++) s[i] = 1LL*(i+1)*mid + a[i];
        sort(s, s+n);
        LL sum = 0;
        for(int i = 0; i < mid; i++) sum += s[i];
        return sum;
    }
    int main()
    {
        scanf("%d%d", &n, &S);
        for(int i = 0; i < n; i++) scanf("%d", &a[i]);
        int l = 0, r = n, mid;
        while(l < r) {
            mid = (l + r + 1)>>1;
            if(slove(mid) <= 1LL*S) l = mid;
            else r = mid - 1;
        }
        if(l == 0) printf("0 0
    ");
        else printf("%d %lld
    ", l, slove(l));
        return 0;
    }
    View Code

    D. Sagheer and Kindergarten(上完课补)

    暂时没看题意

    E. Sagheer and Apple Tree dfs+博弈

    E题的题意大概是,有一个苹果树,每个枝干上有a_i个苹果,Alice与Bob一起做游戏。

    Alice和Bob可以选择下列操作中的一项,否则就输了

    1、如果当前节点为叶子节点,可以把该节点上的一个非空的苹果集合吃掉。

    2、如果当前节点不是叶子节点,可以把该节点上的一个非空的苹果集合移动到它的儿子节点。

    问你如果Alice可以交换两个节点的苹果的数量,那么有多少种交换方法可以使他先手必胜?

    这个题就是一个树上的阶梯博弈(根据lls的启发),也就是一个传统的Nim博弈。

    (上完课补)

  • 相关阅读:
    vue中倒计时的用法
    ant.design 中各种问题
    vue-cli3.0跨域代理问题
    vue-cli3.0配置多页面应用
    vue-axios中post和get携带参数和token
    后台返回的时间戳转化为前端的日期
    微信与支付宝二维码在页面中的使用
    git梗概介绍
    键盘和鼠标事件的区别和使用
    vue.js学习笔记(5)— Vue路由传参
  • 原文地址:https://www.cnblogs.com/cshg/p/6932916.html
Copyright © 2020-2023  润新知