打表法
打表是一种典型的用空间换时间的技巧
一般指将所有可能需要用到的结果事先计算出来,这样后面需要用到时就可以直接查表获得。
打表常见的用法有如下几种:
①在程序中一次性计算出所有需要用到的结果,之后的查询直接取这些结果这个是最常用到的用
法,例如在一个需要查询大量 Fibonacci数 Fn)的问题中,显然每次从头开始计算是非常耗时的,
对Q 次查询会产生 OnQ)的时间复杂度,而如果进行预处理,即把所有 Fibonacci数预先计算并存
在数组中,那么每次查询就只需要 O(1)的时间复杂度,对Q次查询就只需要 O(+Q)的时间复杂度
(其中 O(n)是预处理的时间)。
②在程序B中分一次或多次计算出所有需要用到的结果,手工把结果写在程序A的数组中,然后在
程序A中就可以直接使用这些结果
这种用法一般是当程序的一部分过程消耗的时间过多,或是没有想到好的算法,因此在另一个程序
中使用暴力算法求出结果,这样就能直接在原程序中使用这些结果。例如对 n皇后问题来说,如果
使用的算法不够好,就容易超时,而可以在本地用程序计算出对所有 n来说 n皇后问题的方案数,
然后把算出的结果直接写在数组中,就可以根据题目输入的 n来直接输出结果。
③对一些感觉不会做的题目,先用暴力程序计算小范围数据的结果,然后找规律,或许就能发现一
些“蛛丝马迹”。
这种用法在数据范围非常大时容易用到,因为这样的题目可能不是用直接能想到的算法来解决的,
而需要寻找一些规律才能得到结果。
例题:火柴棒等式
给你 n 根火柴棍,你可以拼出多少个形如 A + B = C 的等式? 等式中的 A、B、C 是用火柴棍拼出
的整数(若该数非零,则最高位不能是 ) 。用火柴棍拼数字 0 ~ 9 的拼法如图所示:
注意:
1.加号与等号各自需要两根火柴棍
2.如果 A= B,则A+B=C与B + A= C视为不同的等式 (A.B.C > O)3.n 根火柴棍必须全部用上。
输入格式
一个整数 n(1 < n < 24)。
样例:
输入 14 输出 2
这道题n<=20完全可以打表,代码(生成答案):
#include<iostream>
#include<cstdio>
#include<cstring>
using namespace std;
int main(){
freopen("ans.txt","w",stdout);
int a[10]={6,2,5,5,4,5,6,3,7,6};
int i,j,temp=0,num=0,k,in[2020],n;
in[0]=6;
for(i=1;i<=2000;i++){
k=i;
temp=0;
while(k){
temp+=a[k%10];
k/=10;
}
in[i]=temp;
}
n=0;
Again:
num=0;
for(i=0;i<=999;i++){
for(j=0;j<=999;j++){
if(n==in[i]+in[j]+in[i+j]+4) num++;
}
}
printf("%d,",num);
if(n<24){n++;goto Again;}
return 0;
}
提交代码:
#include<iostream>
using namespace std;
int ans[]={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};
int n;
int main(){
cin>>n;
cout<<ans[n]<<'\n';
return 0;
}