• 【CSDN竞赛第11期】编程竞赛总结


    CSDN编程竞赛报名地址:https://edu.csdn.net/contest/detail/16

    前言/背景

    目前已经连续参加10次CSDN的编程竞赛了,这种比赛挺有意义,希望一直举办下去!
    在这里插入图片描述

    题目与解题代码

    本次题目与往常一样有四个,这边贴出我当时的解题代码。

    1. 圆小艺

    在这里插入图片描述

    输入描述:
    
    第一行输入整数n.(1<=n<=1000)表示圆的数量。
    第二行输入n个圆的半径。(1<=r<=1000)
    
    输出描述:
    
    输出染色面积,保留小数点后3位。
    
    输入样例:
    
    3
    1 2 3
    
    输出样例:
    
    18.849
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17

    这题乍一看以为是染色问题,但仔细一想比染色问题简单多了。只需要记录下奇数层圆环的面积和偶数层圆环的面积,然后判断最外层属于偶数层还是奇数层即可。

    #include 
    #include 
    #include 
    #include 
    #include
    #include
    double solution(int n, std::vector<int>& vec){
        sort(vec.begin(),vec.end());
        double result;
        double PI =3.14159265354;
    // TODO:
        double ji_area = 0.0;
        double ou_area = 0.0;
        for(int i=0;i<n;i++){
            if(i%2==0){
                if(i==0){
                    ou_area+=PI*vec[i]*vec[i];
                }else{
                    ou_area+=PI*(vec[i]*vec[i]-vec[i-1]*vec[i-1]);
                }
            }if
                    (i%2!=0){
                ji_area+=PI*(vec[i]*vec[i]-vec[i-1]*vec[i-1]);
            }
        }if
                (n%2==0){
            result=ji_area;
        }else{
            result=ou_area;
        }return result;
    } int main() {
        int n;
        std::vector<int> vec;
        std::cin>>n;
        std::string line_0, token_0;
        getline(std::cin >> std::ws,line_0);
        std::stringstream tokens_0(line_0);
        while(std::getline(tokens_0, token_0, ' ')){
            vec.push_back(std::stoi(token_0));
        }
        double result = solution(n,vec);
        std::cout<<std::fixed<<std::setprecision(3)<<result<<std::endl;
        return 0;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44

    还需要注意的是精度问题,题目要求精度是3位小数,所以 π \pi π需要尽可能地取得精确点。

    2. K皇把妹

    在这里插入图片描述

    输入描述:
    
    第一行输入整数n,m,k.(1<=n,m,k<=100)
    第二行输入n个整数的权值。(1<=a<=1000)
    
    输出描述:
    
    输出最小距离
    
    输入样例:
    
    7 3 50
    62 0 0 0 99 33 22
    
    输出样例:
    
    3
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17

    这题也很简单,从节点 m m m分别向左、向右找满足条件的值即可。

    #include 
    #include 
    #include 
    #include 
    int solution(int n, int m, int k, std::vector<int>& vec){
        int result=0;
    // TODO:
        int start = m-1;
        int index1 = -10000;
        int index2=-10000;
        for(int i=start+1;i<n;i++){
            if(k>=vec[i]&&vec[i]>0){
                index1=i;
                break;
            }
        }
        for(int i=start-1;i>=0;i--){
            if(k>=vec[i]&&vec[i]>0){
                index2=i;
                break;
            }
        }
        result = abs(start-index1)>abs(start-index2)?abs(start-index2):abs(start-index1);
        return result;
    } 
    int main() {
        int n;
        int m;
        int k;
        std::vector<int> vec;
        std::cin>>n;
        std::cin>>m;
        std::cin>>k;
        std::string line_0, token_0;
        getline(std::cin >> std::ws,line_0);
        std::stringstream tokens_0(line_0);
        while(std::getline(tokens_0, token_0, ' ')) {
            vec.push_back(std::stoi(token_0));
        }
        int result = solution(n, m, k,vec);
        std::cout<<result<<std::endl;
        return 0;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43

    3. 筛选宝物

    在这里插入图片描述

    输入描述:
    
    第一行输入宝物的数量n(1<n<100)和可选择宝物的总质量M(0<=M<=1000)。
    以下n行每行输入两个数m和v(1<m<100, 1<v<100),表示这n个宝物其各自的重量和价值。
    
    
    输出描述:
    
    输出最优方案下能获取的最大价值V。
    说明:
    
    v代表每个宝物自己的价值
    
    m代表每个宝物的质量
    
    V代表最大价值
    
    M代表总质量
    
    输入样例:
    
    5 10
    2 3
    5 3
    4 5
    6 2
    4 2
    
    输出样例:
    
    10
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31

    这是一道经典的背包问题。背包问题的讲解非常推荐看代码随想录

    #include 
    #include 
    #include 
    #include 
    int solution(int n, int M, std::vector<std::vector<double>>& vec){
        int result;
    // TODO:
        std::vector<std::vector<double>>dp(n,std::vector<double>(M+1,0));
        for(int j=vec[0][0];j<=M;++j){
            dp[0][j]=vec[0][1];
        }
        for(int i=1;i<n;i++){
            for(int j=0;j<=M;j++){
                if(j<vec[i][0])dp[i][j]=dp[i-1][j];
                else{
                    dp[i][j]=dp[i-1][j]>dp[i-1][j-vec[i][0]]+vec[i][1]?dp[i-1][j]:dp[i-1][j-vec[i][0]]+vec[i][1];
                }
            }
        }
        result = dp[n-1][M];
        return result;
    } 
    int main() {
        int n;
        int M;
        std::cin >> n;
        std::cin >> M;
        std::vector<std::vector<double>> vec(n, std::vector<double>(2));
        for (int i = 0; i < n; i++) {
            std::cin >> vec[i][0] >> vec[i][1];
        }
        int result = solution(n, M, vec);
        std::cout << result << std::endl;
        return 0;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35

    4. 圆桌

    在这里插入图片描述

    输入描述:
    
    第一行输入一个整数N,(1<=N<=10000),代表客人的数量
    接下来N行,每行两个整数li与ri,(1<=i<=N,1<=li<=ri<=1000000000)
    代表第i位客人希望左边有li个空座位,右边有ri个空座位。
    
    输出描述:
    
    输出一个整数,代表主人需要准备的最少座位数量。
    
    输入样例:
    
    3
    1 1
    1 1
    1 1
    
    输出样例:
    
    6
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20

    这一题对我来说难度挺高,我也不知道怎么做。。所以当时用非常投机取巧的方式过了 40 % 40\% 40%

    #include 
    #include 
    #include 
    #include 
    int solution(int n, std::vector<std::vector<int>>& vec){
        int result=0;
    // TODO:
        result+=n;
        for(int i=0;i<vec.size();i++){
            if(vec[i][0]>vec[i][1]){
                result+=vec[i][0];
            }else{
                result+=vec[i][1];
            }
        }
        return result;
    } int main() {
        int n;
        std::cin >> n;
        std::vector<std::vector<int>> vec(n, std::vector<int>(2));
        for (int i = 0; i < n; i++) {
            std::cin >> vec[i][0] >> vec[i][1];
        }
        int result = solution(n, vec);
        std::cout << result << std::endl;
        return 0;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27

    后面看别人题解时说是一道原题,原题出处戳此,属于贪心题型。

    正确解法如下:

    #include 
    #include 
    #include 
    #include 
    #include 
    int solution(int n, std::vector<std::vector<int>>& vec){
        int result=0;
    // TODO:
        std::vector<int>left(n),right(n);
        for(int i=0;i<n;i++){
            left[i]=vec[i][0];
            right[i]=vec[i][1];
        }
    
        sort(left.begin(),left.end());
        sort(right.begin(),right.end());
        result = n;
        for(int i=0;i<n;i++){
            result+=std::max(left[i],right[i]);
        }
    
        return result;
    } int main() {
        int n;
        std::cin >> n;
        std::vector<std::vector<int>> vec(n, std::vector<int>(2));
        for (int i = 0; i < n; i++) {
            std::cin >> vec[i][0] >> vec[i][1];
        }
        int result = solution(n, vec);
        std::cout << result << std::endl;
        return 0;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
  • 相关阅读:
    数据结构——分块查找
    【已解决】QT设置setMouseTracking不响应mouseMove
    如何增强 ABAP 系统,允许开发人员给 ABAP 对象设置标签,方便快速检索
    二维傅立叶变换与卷积定理算法
    SpringBoot中pom.xml不引入依赖, 怎么使用parent父项目的依赖
    Xpath的使用
    iOS——Autoreleasepool底层原理
    【Webpack】打包资源的名称路径和清空打包资源
    LRTA*(Learning-RTA*)
    Java:如何去优雅地优化接口
  • 原文地址:https://blog.csdn.net/weixin_42301220/article/details/128147621