蓝桥杯备赛---------数的分解(学习笔记)

一、题目描述

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

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

运行限制

  • 最大运行时间:1s
  • 最大运行内存: 128M

二、解题思路

将2019分解成三个正整数,我们第一时间想到的就是通过三层for循环对三个正整数组合进行枚举,同时每枚举出一组正整数组合后,我们都要对这三个数进行检查,是否包含数字2或4,如果包含那么就pass掉这个组合。但这种代码实现会出现运行超时的情况,我们需要减少循环次数,那么我们可以将第一层for循环里的两层for循环减少为一层,题干中有一个重要的关注点,“例如 1000+1001+18 和 1001+1000+18 被视为同一种。”,所以三个正整数组合会因为位置不同而有三种呈现方式,我们只需取一种,因为三个正整数互不相同,所以一定会有大小关系,我们姑且选择升序的排列方式,当确定了第一个正整数i,那么我们接下来确定第二个正整数j,先让j等于i+1,然后进入while循环,得到第三个数k=2019-i-j,如果k<=j那么退出while循环,如果符合条件那么成功分解方法数加一,然后j加一,找到所有在当前i情况下所有符合条件的分解方法。

三、代码实现

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
bool check(int x)
{
  while(x)
  {
    int a = x % 10;
    if(a == 2 || a == 4)
    {
      return 0;
    }
    x /= 10;
  }
  return 1;
}
int main()
{
  ll cnt = 0;
  for(int i = 1; i < 2019; ++ i)		//三层for循环会运行超时,所以要减少循环次数 
  {
    int j = i + 1;
    while(true)
    {
    	int k = 2019 - i - j;
    	if(k <= j)
    		break;
    	if(check(i) && check(j) && check(k))
    		cnt++;
    	j++;
	}
  }
  cout<<cnt<<endl;
  return 0;
}
 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值