用Python写算法题--洛谷P1149 火柴棒等式
题目
题目来源
P1149 火柴棒等式,https://www.luogu.org/problem/P1149
题目描述
给你n根火柴棍,你可以拼出多少个形如“A+B=C”的等式?等式中的A、B、C是用火柴棍拼出的整数(若该数非零,则最高位不能是00)。用火柴棍拼数字0-90−9的拼法如图所示:

注意:
- 加号与等号各自需要两根火柴棍
- 如果A≠B,则A+B=C与B+A=C视为不同的等式(A,B,C>=0)
- n根火柴棍必须全部用上
输入格式
一个整数n(n<=24)。
输出格式
一个整数,能拼成的不同等式的数目。
输入输出样例
样例1:
输入
14
输出
2
样例2
输入
18
输出
9
解法
方法1:暴力打表法
因为n的最大值只有24,那么可以直接提前把答案穷举出来。
# 0-9需要多少根火柴棒
num =[6, 2, 5, 5, 4, 5, 6, 3, 7, 6]
# 输入一个数,计算需要多少火柴棒
def count(x):
if x == 0:
return 6
c = 0
while x > 0:
digit = x % 10
c += num[digit]
x = x // 10
return c
result = [0] * 24
for n in range(10, 25): #10根火柴以下都是0,很明显
print("caculate ", n)
for i in range(0, 10000): #假设单个数字最大值为10000
for j in range(0, 10000):
if count(i) + count(j) + count(i+j) == n - 4:
result[n-1] += 1
print(result)
上述代码在我的电脑上跑半天也出不来,最大值改成2000就可以。同样的代码,用Java很快就出结果了,足以说明Python并不适合这一类的题目。
public class Test {
public static void main(String[] args) {
int[] result = new int[24];
for(int i = 10; i <= 24; i++) {
for(int j = 0; j < 10000; j++) {
for(int k = 0; k < 10000; k++) {
if(count(j) + count(k) + count(j+k) == i - 4) {
result[i] += 1;
}
}
}
}
for(int i = 0; i < 24; i++) {
System.out.println(result[i]);
}
}
public static int[] num = {6,2,5,5,4,5,6,3,7,6};
public static int count(int x) {
if(x == 0) {
return 6;
}
int c = 0;
while (x > 0) {
int digit = x % 10;
c += num[digit];
x = x / 10;
}
return c;
}
}
最后结果是{0,0,0,0,0,0,0,0,0,0,0,0,0,1,2,8,9,6,9,29,39,38,65,88,128}。
但是虽然是暴力穷举,但是上面代码有个问题,每次都要重复调用count,提前把count存起来就行了,虽然用Python还是很慢,但是能够在可接受时间内出结果。
# 0-9需要多少根火柴棒
num =[6, 2, 5, 5, 4, 5, 6, 3, 7, 6]
# 输入一个数,计算需要多少火柴棒
def count(x):
if x == 0:
return 6
c = 0
while x > 0:
digit = x % 10
c += num[digit]
x = x // 10
return c
COUNT = [0] * 20000
for i in range(0, 20000):
COUNT[i] = count(i)
result = [0] * 24
for n in range(10, 25):
print("caculate ", n)
for i in range(0, 10000):
for j in range(0, 10000):
if COUNT[i] + COUNT[j] + COUNT[i+j] == n - 4:
result[n-1] += 1
print(result)
方法2:优化上述方法
没有什么更好的方法,我们可以尽量减少循环次数,另外,如果能知道单个数的最大值,那就更好办了。
要想用最少的火柴棒拼出最大的数,那优先得拼出最大的数字个数,因为999肯定要比1111小,因为一个数字至少2个火柴,所以对于偶数个火柴,肯定是用拼成11111这样的最大,例如10根火柴,能拼出的最大数是11111,20个火柴,能拼出的最大数是1111111111。
假设最大值超过10000,那至少需要10根,能拼出11111,剩下10根分成8+2根,两个凑起来不可能超过10000,所以最大值不超过10000。
假设最大值可能位于[9000,10000),至少需要12根,能拼出9111,剩下8根不可能加起来等于这个数。
假设最大值可能位于[8000,9000),至少需要13根,更不可能。
假设最大值可能位于[7000,8000),至少需要9根,也就是7111,剩下11根,,如果分成9+2,2根只能是1,所以9根必须拼成7110,不够数。
假设最大值可能位于[6000,7000),至少需要12根,剩下8根也不行。
假设最大值可能位于[5000,6000),至少需要11根,剩下9根能拼出的最大4位数是7xxx或者1xxx,加起来不可能是5000。对于[2000,5000)也一样。
假设最大值可能位于[1900,2000],那么最少需要12根,1911,剩下的没法相加为1911。
依次分析,我们发现最大数不可能大于1111。通过程序结果来看,最大值为712。
改进之后,不用打表也能AC。
# 0-9需要多少根火柴棒
num =[6, 2, 5, 5, 4, 5, 6, 3, 7, 6]
# 输入一个数,计算需要多少火柴棒
def count(x):
if x == 0:
return 6
c = 0
while x > 0:
digit = x % 10
c += num[digit]
x = x // 10
return c
COUNT = [0] * 713
for i in range(0, 713):
COUNT[i] = count(i)
result = 0
n = int(input())
for i in range(0, 712):
for j in range(0, 712):
if i + j > 712:
continue
if COUNT[i] + COUNT[j] + COUNT[i+j] == n - 4:
result += 1
print(result)
用Python写算法题--洛谷P1149 火柴棒等式的更多相关文章
- (水题)洛谷 - P1149 - 火柴棒等式
https://www.luogu.org/problemnew/show/P1149 一开始还分类重复了.在非0的dfs中居然赋值了0,脑残得一笔. 其实就按 $lead0$ 分类就好了, $lea ...
- 洛谷 P1149 火柴棒等式
嗯.... 这道题好讨厌啊!!!! 一开始莫名RE,然后发现数组小了,然后发现后面几个点总是WA,原来推的少了.... 并且这道题的思路真的好水啊!! 先看一下题: 题目描述 给你n根 ...
- 洛谷P1149.火柴棒等式(暴力搜索)
题目描述 给你n根火柴棍,你可以拼出多少个形如"A+B=C"的等式?等式中的A.B.C是用火柴棍拼出的整数(若该数非零,则最高位不能是0).用火柴棍拼数字0-9的拼法如图所示: 注 ...
- 洛谷P1149 火柴棒等式
题目描述 给你n根火柴棍,你可以拼出多少个形如“A+B=C”的等式?等式中的A.B.C是用火柴棍拼出的整数(若该数非零,则最高位不能是0).用火柴棍拼数字0-9的拼法如图所示: 注意: 1.加号与等号 ...
- [NOIP2008] 提高组 洛谷P1149 火柴棒等式
题目描述 给你n根火柴棍,你可以拼出多少个形如“A+B=C”的等式?等式中的A.B.C是用火柴棍拼出的整数(若该数非零,则最高位不能是0).用火柴棍拼数字0-9的拼法如图所示: 注意: 加号与等号各自 ...
- Java实现 洛谷 P1149 火柴棒等式
import java.util.HashMap; import java.util.Iterator; import java.util.LinkedList; import java.util.S ...
- (函数)P1149 火柴棒等式
题解: #include<stdio.h>int a[10]={6,2,5,5,4,5,6,3,7,6};int num(int n){ ...
- [折腾笔记] 洛谷P1149-火柴棒等式 AC记
原题链接: https://www.luogu.org/problem/P1149 题面简述: 给你n根火柴棍,你可以拼出多少个形如"A+B=C""A+B=C" ...
- P1149 火柴棒等式
#include <bits/stdc++.h> using namespace std; const int num[] = {6, 2, 5, 5, 4, 5, 6, 3, 7, 6} ...
随机推荐
- 重写TabBar遇到的按钮不显示的问题
这里的控件frame没有进行设置,无法显示 这里初始化的按钮 frame也为0, 因此 在 重写某个控件的时候 一定要调用layoutSubviews这个方法来对这个控件内部的子控件进行赋值
- gulp+webpack+angular1的一点小经验(第三部分使用一些angular1的插件ui-bootstrap与highcharts)
第一个要介绍的是我们的麻烦制造器:angular-ui-bootstrap ui-bootstrap可以有很多通用的插件给大家用,比如弹窗啊(modal),翻页控件啊(pagination),为什么说 ...
- 华为“方舟编译器”到底是啥?一文看懂TA如何让手机性能再突破【华为云技术分享】
版权声明:本文为博主原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接和本声明. 本文链接:https://blog.csdn.net/devcloud/article/detai ...
- 是时候考虑让你的Spark跑在K8S上了
[摘要] Spark社区在2.3版本开始,已经可以很好的支持跑着Kubernetes上了.这样对于统一资源池,提高整体资源利用率,降低运维成本(特别是技术栈归一)有着非常大的帮助.这些趋势是一个大数据 ...
- postman tests常用方法
postman常用方法集合: 1.设置环境变量 postman.setEnvironmentVariable("key", "value"); pm.envir ...
- zabbix监控系统系列
来自网站:http://www.361way.com/zabbix-summarize/3335.html 一.zabbix的特点 zabbix是一个基于WEB界面的提供分布式系统监视以及网络监视功能 ...
- 当用python读取几十万行文本时,会出现什么状况?
前言本文的文字及图片来源于网络,仅供学习.交流使用,不具有任何商业用途,版权归原作者所有,如有问题请及时联系我们以作处理.作者:accumulate_zhang 我在使用python读取几十 ...
- protobuf-rpm
############################################################## # http://www.rpm.org/max-rpm/ch-rpm-i ...
- mysql 根据某个值叠加查询
今天看到需求 根据输入用户ID由近到远排列 怎么会有这种需求??? 直接上代码 SELECT * FROM Member, ( (SELECT ABS(ID-900) as Sorting,ID FR ...
- 笔记||Python3之对象的方法
什么是对象的方法? python中的一切类型的数据都是对象. 对象:数据和方法 对象数据:如 a = 'sfd' 对象方法:其实就是属于该对象的函数 对象的方法调用:对象.方法 字符串对象常用的方法: ...