1.题目描述:

给你n根火柴棍,你可以拼出多少个形如“A+B=CA+B=C”的等式?等式中的AA、BB、CC是用火柴棍拼出的整 
数(若该数非零,则最高位不能是00)。用火柴棍拼数字0-90−9的拼法如图所示:(我直接把对应的火柴 
数写出来了)
6,2,5,5,4,5,6,3,7,6
注意
加号与等号各自需要两根火柴棍
如果a!=b则A+B=CA+B=C与B+A=CB+A=C视为不同的等式(A,B,C>=0A,B,C>=0)
nn根火柴棍必须全部用上
输入格式:
一个整数n(n<=24)n(n<=24)。
输出格式:
一个整数,能拼成的不同等式的数目。
输入输出样例
输入 #1复制
14
输出 #1复制
2
输入 #2复制
18
输出 #2复制
9
说明/提示:
【输入输出样例1解释
22个等式为0+1=10+1=1和1+0=11+0=1
【输入输出样例2解释】
99个等式为:
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

分析:

结合下面的代码,我们慢慢分析,首先看备注释的部分代码,这部分代表直接计算0-24每一项所用到的火 
柴数,内层的循环中,1000的由来:按火柴数最少1111+1=1112在这时候所用到的数目是25,不符合范 
围,所以说4位数肯定不满足,所以我们a或者b的值遍历到1000就足够了。然后看下面代码的注释。
等到输出完之后,直接打表,就是下面的arr[25];
然后题目中输入a,就输出arr[a]。然后这道题就ac了。

源码:

#include <iostream>
using namespace std;
int pre[]={6,2,5,5,4,5,6,3,7,6};
int arr[25]={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 main(void)
{
  int n;
  cin>>n;
  cout<<arr[n]<<endl;
//  for(int n=0;n<=24;n++)
//  {
//      int arr=0;
//      for(int i=0;i<=1000;i++)
//      {
//          for(int j=0;j<=1000;j++)
//          {
//              int sum=0;
//              int a=i,b=j,c=i+j;
//              if(a==0) sum+=6;  //因为a或b或c为零时,不会进入while循环中
//              if(b==0) sum+=6;
//              if(c==0) sum+=6;
//              while(a)
//              {//这个循环中就是基本的每位用到的火柴数
//                  sum+=pre[a%10];
//                  a=a/10;
//              }
//              while(b)
//              {
//                  sum+=pre[b%10];
//                  b=b/10;
//              }
//              while(c)
//              {
//                  sum+=pre[c%10];
//                  c=c/10;
//              }
//              if(sum==n-4)//sum没有算加号和等号一共4根。
//              {
//                  arr++;
//              }
//          }
//      }
//      cout<<arr<<',';//输出每一项的火柴数所能配成的等式。
//  }
  return 0;
}

2.题目:

给定n个数,让你求这n个数的阶乘和对1e9+7取余为多少?
1<=n<=1e6
1<=a[i]<=1e5

分析:

直接计算的时间复杂度为O(n*m),其中m为max(a[i]),即1e11.

解决办法:

1.那没一个数的阶乘给存下来,a[i]代表的是i的阶乘对mod取余的结果。
2.可以通过O(max(a[i]))的时间复杂度求解出所有数的阶乘并存到a数组里。
3.对于每一次,我们输入x,那么对应的阶乘值就是a[x]。
4.这样实现每一次计算的复杂度为O(1)。
5.总体时间复杂度为O(n+max(a[i]))。

源码:

#include <iostream>
using namespace std;
const int mod=1e9+7;
const int maxn=1e5+9;
long long pre[maxn];
int main()
{
    pre[1]=1;
    for(int i=2;i<=100000;i++)
    {
        pre[i]=pre[i-1]*i;
        pre[i]=pre[i]%mod;
    }
    int n;
    cin>>n;
    long long ans=0;
    while(n--)
    {
        int x;
        cin>>x;
        ans+=pre[x];
        ans%=mod;
    }
    cout<<ans<<endl;
    return 0;
}