[蓝桥杯][2013年第四届真题]带分数

题目

题目链接

题解

全排暴力。


规定一下:n = sum1 + sum2/sum3

使用next_permutation()函数对保存着1、2、……、9的数组进行全排列,对于每一种全排列,我们对其进行分段,分成三段,第一段构成sum1第二段构成sum2第三段构成sum3 。算出三段的大小,判断是否满足上面等式即可。


我裂开,我想了好久,心想暴力肯定不行时间必超,觉得一定是个思维题,结果我想多了,扫了一眼网上题解的第一句话“全排”,我就试着算了一下9!=362880,妈的,我居然觉得9!会特别大,结果才不到4e5。

这说明几个问题:

  • 我是《小可爱》
  • 蓝桥杯是暴力杯
  • 蓝桥杯也是《小可爱》

时间上限且是无法触及的上限,大概是9! * 7 * 7 < 2e7
算的不准确,反正肯定比这个小。

代码

#include<bits/stdc++.h>
using namespace std;

int a[10] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9};
int n, ans;

// 9! = 362880
int main()
{
	cin>>n;
	int x = n, sn = 0;
	while(x) sn ++, x/=10; // sn保存n的size,即n的位数 
	
	while(next_permutation(a+1, a+10)) { // 全排 
		for(int s1 = 1;s1 <= sn;s1 ++) { // sum1的位数最起码不能超过n的位数吧 
			int sum1 = 0;
			for(int i = 1;i <= s1;i ++) sum1 = sum1*10 + a[i]; // 计算sum1 
			if(sum1 > n) break; // 如果sum1的值都大于n了,显然不行,之后增加长度只会让sum1变大,因此直接break就可以 
			int r = n-sum1; // n减去sum1还剩多少 
			for(int s2 = (9-s1+1)/2;s2 <= 8-s1;s2 ++) { // 枚举sum2的长度,长度从 (9-sum1的长度+1)/2 开始是为了保证sum2的长度要 >= sum3的长度,这是sum2/sum3>0的必要条件,用这个开始相当于避免一些无用的判断 
				int sum2 = 0, sum3 = 0;
				for(int j = s1+1;j <= s1+s2;j ++) sum2 = sum2*10 + a[j]; // 计算sum2 
				for(int j = s1+s2+1;j <= 9;j ++) sum3 = sum3*10 + a[j]; // 计算sum3 
				if(r * sum3 == sum2) ans++; // 若满足和为n,则ans++ 
			}
		}
	}
	
	cout<<ans<<endl;
	return 0;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

不牌不改

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值