C++:蓝桥杯-22真题-最大数字

C++:蓝桥杯-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的位数nums作为退出条件来获取当前的最大值
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-2allsobaiduweb~default-8-125345906.142v73wechat,201v4add_ask,239v2insert_chatgpt&spm=1018.2226.3001.4187#t4

猜你喜欢

转载自blog.csdn.net/Bellwen/article/details/129477393
今日推荐