数的分解
问题描述
把2019分解成3个各不相同的正整数之和,并且要求每个正整数都不包含数字2和4.一共有多少种不同的分割方法。
注意交换3个整数的顺序被视为同一种方法1,例如1000+1001+18和1001+1000+18被视为同一种。
答案提交
这是一道结果填空的题,你只需要算出结果后提交即可。本题的结果为一个整数,在提交答案时只填写这个整数,填写多余的内容将无法得分。
题目来源
第十届蓝桥杯软件类省赛B组
题解
去除不满足条件的情况
首先题目要求,所有的数字不应该含有2或者4。那么我们在遍历的时候,就需要判断出哪个数字是含有2或4的,我们只让不含有的参与运算。因此,需要先编写一个函数,能够判断是否含有数字2或4。
那么如何编写这个函数呢?这里提供的思路是,通过循环一位一位的判断,只要这个数字有一位含有2或者4,就返回一个false。
示例如下:
bool check(int number) //类型为布尔型,参数为需要判断的数
{
while(number>0)
{
if(number%10==2 || number%10==4)//判断最后一位是否是2或4
{
return false;//若是,返回假
}
number/=10;//每判断一位,就要再判断前一位
}
return true;//如果都不满足,则返回
}
去除重复的情况
另外,这道题要注意的是,不允许有重复的分割方法。因为如果单纯的使用暴力循环,从第一次一直遍历到最后一次,总会出现同样的情况。
例如题目所给,假如现在找到的第一个数是1000,那么很容易得到它所对应的分割方法,其中之一是1000+1001+18。
那么我们继续向后遍历,这时的第一个数是1001,也很容易能够得到1001+1000+18这个分割方法。然而我们发现,它与上一次循环中找到的分割方式是重复的。因此,如果以这种方式遍历,我们最终得到的分割方法一定比实际的要多。
所以为了解决这个问题,我们在嵌套循环时,要设置第二个数始终大于第一个数。因此当我们最外层的增量为i时,第二层的自增量为i+1。(只需要两层循环,因为只要确定了2个数字,第三个数也就随之确定)
全代码如下:
#include <bits/stdc++.h>
using namespace std;
bool check(int number) //类型为布尔型,参数为需要判断的数
{
while(number>0)
{
if(number%10==2 || number%10==4)//判断最后一位是否是2或4
{
return false;//若是,返回假
}
number/=10;//每判断一位,就要再判断前一位
}
return true;//如果都不满足,则返回
}
int main() {
int N = 2019;
int count = 0;
for (int i = 1; i < N / 3; ++i)
if (check(i))//如果第一个数就不满足,就不用再往下判断
// k = N - i - j > j;
for (int j = i + 1;N - i - j > j; ++j)
if (check(j) && check(N - i - j)) //后两个数,必须都满足
++count;
cout << count << endl;
return 0;
}