每周一题(1)

数的分解

问题描述

把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;
}
发布了11 篇原创文章 · 获赞 13 · 访问量 2873

猜你喜欢

转载自blog.csdn.net/lhx0525/article/details/103612580
今日推荐