P1149 火柴棒等式
---恢复内容开始---
题目描述
给你n根火柴棍,你可以拼出多少个形如“A+B=CA+B=CA+B=C”的等式?等式中的AAA、BBB、CCC是用火柴棍拼出的整数(若该数非零,则最高位不能是000)。用火柴棍拼数字0−90-90−9的拼法如图所示:
注意:
-
加号与等号各自需要两根火柴棍
-
如果A≠BA≠BA≠B,则A+B=CA+B=CA+B=C与B+A=CB+A=CB+A=C视为不同的等式(A,B,C>=0A,B,C>=0A,B,C>=0)
-
nnn根火柴棍必须全部用上
输入输出格式
输入格式:
一个整数n(n<=24)n(n<=24)n(n<=24)。
输出格式:
一个整数,能拼成的不同等式的数目。
输入输出样例
说明
【输入输出样例1解释】
222个等式为0+1=10+1=10+1=1和1+0=11+0=11+0=1。
【输入输出样例2解释】
999个等式为:0+4=4 0+11=11 1+10=11 2+2=4 2+7=9 4+0=4 7+2=9 10+1=11 11+0=11
-----------------------------------------------------------------------------------
官方说这是一道打表题
于是我就开始动笔算了
算了会儿发现
可能性太多了
算不过来
于是就放弃了
然而我忘记了
用计算机打表啊等个10分钟1个点的都没问题啊
唉
傻了傻了
(加号和等于号一共是4根火柴应该是很好想的了)(也还是想到了的)
用来打表的代码
#include<iostream> using namespace std; const short cl[10] = { 6,2,5,5,4,5,6,3,7,6 }; short lx(int cn) { short sm = 0; do { sm += cl[cn % 10]; cn /= 10; } while (cn != 0); return sm; } int main() { bool f = false; for(short a=0;a<=1111;a++) for (short b = 0; b <= 1111; b++) { short c = a + b; short on = lx(a) + lx(b) + lx(c); if (on <= 20) { cout << a << " " << b << " " << c << " " << on << endl; f = true; } } if (!f) cout << "No."; return 0; }
这样就会得到一堆可行的方案
可是太多了
怎么办啊
自己统计会出错的啊
还好
还可以小小的优化一下
一个新程序的代码: #include<iostream> using namespace std; const short cl[10] = { 6,2,5,5,4,5,6,3,7,6 }; short lx(int cn) { short sm = 0; do { sm += cl[cn % 10]; cn /= 10; } while (cn != 0); return sm; } int main() { short ans[12] = { 0,0,0,0,0,0,0,0,0,0,0,0 }; for (short a = 0; a <= 711; a++) for (short b = 0; b <= 711; b++) { short c = a + b; short on = lx(a) + lx(b) + lx(c); if (on <= 20) ans[on - 9]++; } for (short i = 0; i <= 11; i++) cout << i + 13 << " " << ans[i] << endl; return 0; }
这样就会得到下面的样子了
13 1 14 2 15 8 16 9 17 6 18 9 19 29 20 39 21 38 22 65 23 88 24 128
这样就可以打表了
但是不要用一堆的if
(会慢一点的,而且代码风格也太不美观了吧qwq)
#include<iostream> using namespace std; int main() { const short a[12] = { 1,2,8,9,6,9,29,39,38,65,88,128 }; short n; cin >> n; if (n <= 12) cout << 0; else cout << a[n - 13]; return 0; }