• 题解 CF777B 【Game of Credit Cards】


    题目思路

    有点类似于田忌赛马的问题,可以想到用贪心的最优策略

    第一解

    SSS最小受罚次数

    MMM可以按任意顺序拿出数字,枚举遍历SSS中的每一个数,对于每一个数 aaa 只有两种情况:

    • W中有还未用且 ≥ a 的数,此时选满足条件的最小的数
    • W中的数都 < a 的数, 此时选未用的数中最小的数

    代码实现

    for (int i = 1; i <= len; i++) {
            bool ok = 0;
            for (int j = 1; j <= len; j++) 
                if (a[j] >= b[i] and !used[j])  {ok = 1, used[j] = 1; break;}    
            if (!ok)
                for (int j = 1; j <= len; j++)
                    if (!used[j])  {used[j] = 1, ans1++;   break;}
        }

    第二解

    MMM最大受罚数

    做法相似,枚举遍历SSS中的每一个数,对于每一个数aaa只有两种情况:

    • W中有还未用且 > a 的数,此时选满足条件的最小的数
    • W中的数都 ≤ a 的数, 此时选未用的数中最小的数

    代码实现

    for (int i = 1; i <= len; i++) {
            bool ok = 0;
            for (int j = 1; j <= len; j++) 
                if (a[j] > b[i] and !used[j])  {ok = 1, used[j] = 1, ans2++; break;}    
            if (!ok)
                for (int j = 1; j <= len; j++)
                    if (!used[j])  {used[j] = 1;   break;}
        }

    完整代码

    #include <bits/stdc++.h>
    using namespace std;
    char a[1005], b[1005];
    bool used[1005];  //used记录是否被用 
    int len, ans1, ans2; //ans1记录 M 最少受罚次数, ans2记录 S 最多受罚次数 
    int main() {
        scanf ("%d %s %s", &len, b + 1, a + 1);
        sort (a + 1, a + len + 1);
        //第一问: 
        for (int i = 1; i <= len; i++) {
            bool ok = 0;   //ok记录是否有满足要求的数 
            for (int j = 1; j <= len; j++) 
                if (a[j] >= b[i] and !used[j])  {ok = 1, used[j] = 1; break;} 
            //如果没有则选最小的数    
            if (!ok)
                for (int j = 1; j <= len; j++)
                    if (!used[j])  {used[j] = 1, ans1++;   break;}  //此时受罚次数 +1; 
        }
        memset (used, 0, sizeof (used));   //清零used数组 
        //第二问:  
        for (int i = 1; i <= len; i++) {
            bool ok = 0;   //ok记录是否有满足要求的数 
            for (int j = 1; j <= len; j++) 
                if (a[j] > b[i] and !used[j])  {ok = 1, used[j] = 1, ans2++; break;}
            //如果没有则选最小的数    
            if (!ok)
                for (int j = 1; j <= len; j++)
                    if (!used[j])  {used[j] = 1;   break;}   //此时不受罚次数 +1; 
        }
        printf ("%d
    %d", ans1, ans2);
        return 0;
    }
  • 相关阅读:
    java 多线程学习(一)
    解决安卓微信浏览器刷新问题
    sublime text3 配置tab为4个空格
    React 错误Each child in an array or iterator should have a unique “key” prop
    git filename to long问题解决
    JS获取URL参数 方法
    CSS超出2行省略号
    JS判断是否为安卓orIOS
    获取移动设备真实宽高
    微信分享朋友圈监听(PHP)
  • 原文地址:https://www.cnblogs.com/Sworddust/p/11427880.html
Copyright © 2020-2023  润新知