【蓝桥杯】 C++ 数的分解

文章目录

    • 题目描述
    • 实现代码
    • 解题思路
    • 注意点
    • 知识点

题目描述

本题为填空题,只需要算出结果后,在代码中使用输出语句将所填结果输出即可。

把 2019 分解成 3 个各不相同的正整数之和,并且要求每个正整数都不包含数字 2 和 4,一共有多少种不同的分解方法?

注意交换 3 个整数的顺序被视为同一种方法,例如 1000+1001+18 和 1001+1000+18 被视为同一种。

实现代码

1、优化版本,运行时间比较短

#include
using namespace std;

// 判断这个数有没有2或者4
int chk(char* s)
{
    int len=strlen(s);
    for(int i=0;i<len;i++)
    {
        if(s[i]=='2'||s[i]=='4')
        {
            return false;
        }
    }
    return true;
}

int main()
{
    int n=2019;
    int count=0;
    char s[10]={0};

    // 遍历到2019,加和是n就count++
    for(int i=1;i<n;i++)
    {
        sprintf(s,"%d",i);
        if(chk(s)==false)
        {
            continue;
        }

        for(int j=i+1;j<n;j++)
        {
            sprintf(s,"%d",j);
            if(chk(s)==false)
            {
                continue;
            }
            
            int k=n-i-j;
            sprintf(s,"%d",k);
            if(chk(s)==false)
            {
                continue;
            }
            if(j<k)
            {
                count++;
            }
            
            //count++;
        }
    }
    cout<<count;
}

2、无优化,(比较)暴力解

#include
using namespace std;

// 判断这个数有没有2或者4
int chk(char* s)
{
    int len=strlen(s);
    for(int i=0;i<len;i++)
    {
        if(s[i]=='2'||s[i]=='4')
        {
            return false;
        }
    }
    return true;
}

int main()
{
    int n=2019;
    int count=0;
    char s[10]={0};

    // 遍历到2019,加和是n就count++
    for(int i=1;i<n;i++)
    {
        sprintf(s,"%d",i);
        if(chk(s)==false)
        {
            continue;
        }

        for(int j=i+1;j<n;j++)
        {
            sprintf(s,"%d",j);
            if(chk(s)==false)
            {
                continue;
            }
            for(int k=j+1;k<n;k++)
            {
                sprintf(s,"%d",k);
                if(chk(s)==false)
                {
                    continue;
                }
                if(i+j+k==n)
                {
                    count++;
                }
            }
        }
    }
    cout<<count;
}

解题思路

这个题看起来人畜无害很简单,但是很多烦的地方。比如它规定数字中不能有 2 和 4,对于这种要求了数字是多少的题我总是招架不来,水平太次了……

未优化的思路就是三个循环暴力解,因为不需要重复解,所以在 for 循环内部可以先简单优化一下,让每一个循环变量从前一个开始。然后在循环内部判断数字是否包含 2 或者 4 ,最后的循环内部判断三个数加起来是否为 2019 ,如果是,count++,最后输出。

优化后的思路是进行两次循环,第三个数通过前两次循环算出来,再判断是否有 2 或者 4,然后约束其比第二个数大,就可以了。

注意点

  • 注意判断这个数是否有 2 或者 4。
  • 注意每个循环内部都要对数字判断。
  • 注意优化后的思路,第三个数算出来之后还要比第二个数大,不然会多很多。

知识点

  • sprintf 函数的用法:把后面的数格式化以后存到前面的 char 型数组内。
    【蓝桥杯】 C++ 数的分解_第1张图片
  • 判断某个数内部是否有特定数字:
// 判断这个数有没有2或者4
int chk(char* s)
{
    int len=strlen(s);
    for(int i=0;i<len;i++)
    {
        if(s[i]=='2'||s[i]=='4')
        {
            return false;
        }
    }
    return true;
}

你可能感兴趣的:(蓝桥杯,蓝桥杯,c++,算法)