火柴棒等式 (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
A、B、C 是用火柴棍拼出的整数(若拼出的整数不是
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)
(A、B、C≥0)
3.
3.
3.
n
n
n 根火柴棍必须全部用上
格式
输入格式 (matches.in)
输入共一行,一个整数 n ( n ≤ 24 ) n (n \leq 24) n(n≤24),表示火柴数
输出格式 (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;
}