火柴棒等式 (matches)

火柴棒等式 (matches)

  • 内存限制:128MB
  • 时间限制:1000ms
  • 文件输入输出
    • 输入文件 matches.in
    • 输出文件 matches.out

题目

题目描述

给你 n n n 根火柴棍,你可以拼出多少个形如 " A + B = C A+B=C A+B=C " 的等式
等式中的 A 、 B 、 C A、B 、C ABC 是用火柴棍拼出的整数(若拼出的整数不是 0 0 0,这个数的最高位就不能是 0 0 0
用火柴棍拼数字 0 0 0 ~ 9 9 9 的拼法如图所示:
在这里插入图片描述

题目备注

1. 1. 1. 加号与等号各自需要两根火柴棍
2. 2. 2. A ≠ B A \neq B A=B ,则 A + B = C A + B = C A+B=C B + A = C B + A = C B+A=C 视为不同的等式 ( A 、 B 、 C ≥ 0 ) (A、B、C \geq 0) (ABC0)
3. 3. 3. n n n 根火柴棍必须全部用上

格式

输入格式 (matches.in)

输入共一行,一个整数 n ( n ≤ 24 ) n (n \leq 24) n(n24),表示火柴数

输出格式 (matches.out)

输出共一行,一个整数,表示能拼成的不同等式的数目。

样例

样例1

样例输入
14
样例输出
2
样例解释

2 2 2 个等式为:
0 + 1 = 1 0 + 1 = 1 0+1=1
1 + 0 = 1 1 + 0 = 1 1+0=1

样例2

样例输入
18
样例输出
9
样例解释

9 9 9 个等式为:
0 + 4 = 4 0 + 4 = 4 0+4=4
0 + 11 = 11 0 + 11 = 11 0+11=11
1 + 10 = 11 1 + 10 = 11 1+10=11
2 + 2 = 4 2 + 2 = 4 2+2=4
2 + 7 = 9 2 + 7 = 9 2+7=9
4 + 0 = 4 4 + 0 = 4 4+0=4
7 + 2 = 9 7 + 2 = 9 7+2=9
10 + 1 = 11 10 + 1 = 11 10+1=11
11 + 0 = 11 11 + 0 = 11 11+0=11


思路

根据题目所求,我们可以用 n u m [ n ] num[n] num[n] 来储存 n n n 所需要的火柴棍个数。
( n u m num num 的初始值为 0 0 0 ~ 9 9 9 所需要的火柴棍个数)
然后再暴力循环 A A A B B B,如果 n u m [ A ] + n u m [ B ] + n u m [ A + B ] + 4 = n num[A] + num[B] + num[A + B] + 4 = n num[A]+num[B]+num[A+B]+4=n,则 + + a n s ++ans ++ans
但是这里有一个难点—— A A A B B B 的范围是多少呢?
在草稿纸上可以推出:
1111 + 1111 = 2222 1111+1111=2222 1111+1111=2222 所需要的火柴棍数为 40,已经超出了 n n n 的最大值 24 24 24
我们再次缩小范围—— 911 911 911 811 811 811 711 711 711······
最后发现 A A A B B B 的最大值为 711 711 711,知道 A A A B B B 的范围我们就可以初始化 n u m [ ] num[] num[] 了。
即下面所示:

num[1505] = {}
for (int i = 10; i <= 1500; i++) // 虽然711+711=1422, 但是兔兔想取整百, 所以取了1500 
{
	int sumi = 0, numi = i;
	while (numi)
	{
		sumi += num[numi % 10];
		numi /= 10;
	}
	num[i] = sumi;
}

n u m [ ] num[] num[] 有值之后,就可以暴力循环了。
即:

for (int i = 0; i <= 711; i++)
		for (int j = 0; j <= 711; j++)
			if (num[i] + num[j] + num[i + j] + 4 == N) ++ans;

代码

#include <cstdio>

const int MAXN = 1e5 + 5;
int N;
int ans;
int num[MAXN] = { 6, 2, 5, 5, 4, 5, 6, 3, 7, 6 };

void init()
{
	for (int i = 10; i <= 1500; i++)
	{
		int sumi = 0, numi = i;
		while (numi)
		{
			sumi += num[numi % 10];
			numi /= 10;
		}
		num[i] = sumi;
	}
}

void input_output()
{
	init();
	scanf("%d", &N);
	for (int i = 0; i <= 711; i++)
		for (int j = 0; j <= 711; j++)
			if (num[i] + num[j] + num[i + j] + 4 == N) ++ans;
	printf("%d", ans);
}

int main()
{
	freopen("matches.in", "r", stdin);
	freopen("matches.out", "w", stdout);
	input_output();
	return 0;
}


  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值