题目

题目来源

P1149 火柴棒等式,https://www.luogu.org/problem/P1149

题目描述

给你n根火柴棍,你可以拼出多少个形如“A+B=C”的等式?等式中的A、B、C是用火柴棍拼出的整数(若该数非零,则最高位不能是00)。用火柴棍拼数字0-90−9的拼法如图所示:

注意:

  1. 加号与等号各自需要两根火柴棍
  2. 如果A≠B,则A+B=C与B+A=C视为不同的等式(A,B,C>=0)
  3. 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 火柴棒等式的更多相关文章

  1. (水题)洛谷 - P1149 - 火柴棒等式

    https://www.luogu.org/problemnew/show/P1149 一开始还分类重复了.在非0的dfs中居然赋值了0,脑残得一笔. 其实就按 $lead0$ 分类就好了, $lea ...

  2. 洛谷 P1149 火柴棒等式

    嗯....   这道题好讨厌啊!!!!   一开始莫名RE,然后发现数组小了,然后发现后面几个点总是WA,原来推的少了....   并且这道题的思路真的好水啊!!   先看一下题: 题目描述 给你n根 ...

  3. 洛谷P1149.火柴棒等式(暴力搜索)

    题目描述 给你n根火柴棍,你可以拼出多少个形如"A+B=C"的等式?等式中的A.B.C是用火柴棍拼出的整数(若该数非零,则最高位不能是0).用火柴棍拼数字0-9的拼法如图所示: 注 ...

  4. 洛谷P1149 火柴棒等式

    题目描述 给你n根火柴棍,你可以拼出多少个形如“A+B=C”的等式?等式中的A.B.C是用火柴棍拼出的整数(若该数非零,则最高位不能是0).用火柴棍拼数字0-9的拼法如图所示: 注意: 1.加号与等号 ...

  5. [NOIP2008] 提高组 洛谷P1149 火柴棒等式

    题目描述 给你n根火柴棍,你可以拼出多少个形如“A+B=C”的等式?等式中的A.B.C是用火柴棍拼出的整数(若该数非零,则最高位不能是0).用火柴棍拼数字0-9的拼法如图所示: 注意: 加号与等号各自 ...

  6. Java实现 洛谷 P1149 火柴棒等式

    import java.util.HashMap; import java.util.Iterator; import java.util.LinkedList; import java.util.S ...

  7. (函数)P1149 火柴棒等式

    题解: #include<stdio.h>int a[10]={6,2,5,5,4,5,6,3,7,6};int num(int n){                          ...

  8. [折腾笔记] 洛谷P1149-火柴棒等式 AC记

    原题链接: https://www.luogu.org/problem/P1149 题面简述: 给你n根火柴棍,你可以拼出多少个形如"A+B=C""A+B=C" ...

  9. P1149 火柴棒等式

    #include <bits/stdc++.h> using namespace std; const int num[] = {6, 2, 5, 5, 4, 5, 6, 3, 7, 6} ...

随机推荐

  1. Oracle基本的增删改查语句--本人使用scott用户中的表

    --感觉有用点个赞^v^ 1 --创建表空间 create tablespace mykebai datafile 'c:\mykebai.dbf' --数据问价存放位置 size 100m --数据 ...

  2. 自学PHP的第22天---ThinkPHP中的路由、ThinkPHP目录结构

    这一切的一切都得从“Hello world”说起!!! 有很多东西在thinkPHP的官方开发文档上其实都有讲到,我在这里只是想记录自己每天坚持学习PHP的情况,今天接触ThinkPHP的路由,路由这 ...

  3. telnet远程登陆

    这篇文章是第二次更新,内容为telnet远程登陆路由器,非常简单.直接进入正题,在网络配通的情况下,为路由器设置登陆密码和管理员密码,就可以通过pc机远程管理路由器或交换机. 目的: 网络拓扑图如下, ...

  4. 【React】354- 一文吃透 React 事件机制原理

    大纲 主要分为4大块儿,主要是结合源码对 react事件机制的原理 进行分析,希望可以让你对 react事件机制有更清晰的认识和理解. 当然肯定会存在一些表述不清或者理解不够标准的地方,还请各位大神. ...

  5. Dubbo源码分析之SPI(二)

    一.概述 本篇文章是dubbo SPI源码分析的第二篇,接着第一篇继续分析dubbo SPI的内容,我们主要介绍 getDefaultExtension() 获取默认扩展点方法. 由于此方法比较简单, ...

  6. 使用FileReader在浏览器读取预览文件(image和txt)

    如标题,之前在某个地方看到因为有Blob的存在,理论上可以在浏览器上查看所有格式的文件.自己想着试试现在暂时只能够查看图片和预览txt文件.其他的比如doc,docx格式的文件查看的时候是乱码 如图: ...

  7. where和having区别

    壹: where后面不能跟聚合函数(sum.avg.count.max.min) having后面可以跟 贰: where和having都能用: select goods_price,goods_na ...

  8. 五分钟学会conda常用命令

    文章目录 conda常用命令 1. 获取版本号 2. 获取帮助 3. 环境管理 4. 分享环境 5. 包管理 conda常用命令 1. 获取版本号 conda --version 或 conda -V ...

  9. Wonder暂停开发,开始写书

    公告 大家好,我们决定暂时停止开发Wonder,但会继续维护当前的Wonder版本(如继续维护官网.在线编辑器.QQ群等). 我们当前的主要任务是 写书:基于Wonder 1.0版本的开发经验,写一本 ...

  10. Docker图形化工具Portainer详解

    一.介绍 说明:   Portainer是易于使用的软件,可为软件开发人员和IT操作人员提供直观的界面.   Portainer为你提供Docker环境的详细概述,并允许你管理容器,镜像,网络和数据卷 ...