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

题目描述

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

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

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

实现代码

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

#include<bits/stdc++.h>
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<bits/stdc++.h>
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 型数组内。
    在这里插入图片描述
  • 判断某个数内部是否有特定数字:
// 判断这个数有没有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;
}
  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值