C++: Blue Bridge Cup - 22 の実際の質問 - 最大数

C++: Blue Bridge Cup - 22 の実際の質問 - 最大数

自作ルールは完全に貪欲トラバーサルにすることはできません。92 ポイントのみです。
貪欲トラバーサルには dfs 深さ優先検索を使用してください



トピック

トピック
トピック


1. 自主規制、92点だけ、ちょっと見てください

コード

アイデア:
1. N の桁を取り出し、最初に上位の桁、次に下位の桁を取り出し、最初に引き算してから足し、
個別のケースを無視して 92 点を渡す

2. DFS 深さ優先検索は貪欲な場合に使用する必要があります。

/*
蓝桥杯22决赛真题-最大数字

思路:
1、把N的各位数取出,先高位后低位,先减后加
通过92分,忽略了个别情况

2、应该采用dfs深度优先搜索贪心
*/

#include "bits/stdc++.h"
using namespace std;

vector<int> num;        //获取N的各位数,num[0]为个位数
long long N, A, B, ans; //A加,B减

//A,加
void process1(int &N)
{
    
    
    if (N == 9)
    {
    
    
        N = 0;
    }
    else
    {
    
    
        N += 1;
    }
}

//B,减
void process2(int &N)
{
    
    
    if (N == 0)
    {
    
    
        N = 9;
    }
    else
    {
    
    
        N -= 1;
    }
}

//获取N的各位数
void getNum(const long long N)
{
    
    
    long long x, y; //x为剔除掉y后的新值,y为获取的各位数
    x = N;
    for (int i = 0; i < 17; i++) //最大位数有17位
    {
    
    
        if (i == 0)
        {
    
    
            num.push_back(N % 10);
        }
        if (x < 10) //x只有一位时跳出循环ong double x;
        {
    
    
            break;
        }
        y = (x / 10) % 10;
        num.push_back(y); //先进低位再进高位
        x = x / 10;
    }
}

void printNum(vector<int> &num)
{
    
    
    // for (vector<int>::iterator it = num.begin(); it != num.end(); it++)
    // {
    
    
    //     cout << *it << " ";
    // }
    // cout << endl
    //      << "-------------" << endl;
    for (int i = num.size() - 1; i >= 0; i--)
    {
    
    
        cout << num[i];
    }
    cout << endl;
}

//并不是全部遍历考虑到,会出现漏的情况,故为92分
void mySolution()
{
    
    
    //先处理高位在处理低位
    for (int i = num.size() - 1; i >= 0; i--)
    {
    
    
        if (A == 0 && B == 0)
        {
    
    
            break;
        }

        if (num[i] <= 8) //0-8,9不动
        {
    
    

            //当加和减都能变9时,先加
            if (num[i] > 5 && B >= (num[i] + 1) && A >= (9 - num[i]))
            {
    
    
                int temp;
                temp = 9 - num[i]; //次数
                A = A - temp;
                while (temp--)
                {
    
    
                    process1(num[i]);
                }
            }

            if (B >= (num[i] + 1)) //够减
            {
    
    
                int temp = num[i] + 1;
                B = B - temp; //减少B次数
                while (temp--)
                {
    
    
                    process2(num[i]);
                }
            }
            else //不够减,用加
            {
    
    
                int temp;
                if (A > (9 - num[i])) //A的次数比加到9还多时
                {
    
    
                    temp = 9 - num[i]; //次数
                    A = A - temp;
                    while (temp--)
                    {
    
    
                        process1(num[i]);
                    }
                }

                else //A的次数刚好到9或者加不到9时,直接用完A
                {
    
    
                    temp = A; //次数
                    A = A - temp;
                    while (temp--)
                    {
    
    
                        process1(num[i]);
                    }
                }
            }
        }
    }
    printNum(num);
}

int main(int argc, const char **argv)
{
    
    
    cin >> N >> A >> B;
    //1操作<=A,2操作<=B,求最大
    getNum(N);
    // 一般方法
    mySolution();

    return 0;
}

2、dfs 貪欲法

コード

//アイデア:
1. N 桁の数値 num を終了条件として使用し、現在の最大値を取得します。
2. 新しい実際の値 a を新しい値として使用します
。 3. 加算と減算のルールに基づいて dfs 深さ優先検索を実行します。最大値を見つけるには

  • dfs 再帰を終了する条件を見つけることに重点を置き、新しい変数を追跡します。
/*
蓝桥杯-22决赛真题-最大卡牌-dfs方法

//思路:
1、以N的位数nums作为退出条件来获取当前的最大值
2、以跟新完的实际值a作为新的值
3、在加和减的规则下进行dfs深度优先搜索找最大的值
*/

#include "bits/stdc++.h"
using namespace std;

long long N, A, B; //A加,B减
long long ans = 0;

//a当前值大小,nums当前位数,A加数,B减数
void dfs(long long a, long long nums, long long A, long long B)
{
    
    
    if (nums == 0) //变量结束,返回结果
    {
    
    
        ans = max(ans, a);
        return;
    }
    int d = a / nums % 10; //d为当前位数值

    //加减规则遍历完
    if (A > 9 - d) //A够加时
    {
    
    
        int temp = A - (9 - d);
        dfs(a + (9 - d) * nums, nums / 10, temp, B);
    }
    else //A全加满
    {
    
    
        dfs(a + nums * A, nums / 10, 0, B);
    }
    if (B != 0)
    {
    
    
        if (B >= d + 1) //B够减时
        {
    
    
            int temp = B - (d + 1);
            dfs(a - nums * d + nums * 9, nums / 10, A, temp); //够减时,减至9,a值跟新应该为先减到原来改位值,再加上改位*9,即123先变103再变193
        }
    }
}
int main(int argc, const char **argv)
{
    
    
    cin >> N >> A >> B;
    long long a, nums;
    a = N;
    nums = 1;
    //获取N的次方数,N=123时,num =10^3 =1000;
    while (a)
    {
    
    
        a /= 10;
        nums *= 10;
    }
    dfs(N, nums / 10, A, B); //dfs遍历所有位数,N=123时,nums=100,10,1,一共三次所以nums/10

    cout << ans << endl;
    return 0;
}

要約する

dfs メソッドに精通しており、dfs 再帰を終了するための条件と新しい変数を見つけることに重点を置きます。https: //blog.csdn.net/m0_58177653/article/details/125345906 ?ops_request_misc=&request_id=&biz_id=102&utm_term=%E8%
を参照してください。
93%9D %E6%A1%A5%E6%9D%AF%E5%8D%A1%E7%89%8C&utm_medium=distribute.pc_search_result.none-task-blog-2 すべて sobaiduweb~default- 8-125345906.142 v73 wechat、 201 v4 add_ask 、239 v2 insert_chatgpt&spm=1018.2226.3001.4187#t4

おすすめ

転載: blog.csdn.net/Bellwen/article/details/129477393