poj 8466 火柴棒等式(预处理+搜索)

来源:互联网 发布:苹果随机抽奖软件 编辑:程序博客网 时间:2024/06/06 03:55

poj 8466 火柴棒等式(预处理+搜索)
总时间限制: 1000ms 内存限制: 65536kB

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

注意:

  1. 加号与等号各自需要两根火柴棍

  2. 如果A≠B,则A+B=C与B+A=C视为不同的等式(A、B、C≥0)

  3. n根火柴棍必须全部用上

输入
输入一个整数n(n≤24)。

输出
输出能拼成的不同等式的数目。

样例输入

5

样例输出

0

首先枚举是很不划算的,因为理论上枚举要枚举到很高位才能覆盖完全,而中间有大量数字含了多火柴棒的数字,浪费严重,所以要用搜索实现预处理,这样一定要注意0这个数字不要漏!
这是本题最大的难点,就是边界条件,一个特殊的点——0的问题,解决了这个问题很快就AC了,所以说做题目要细致。
如果细致的话,就算枚举会TLE,但是只要正确,打表也可以过。所以因为不细致十分就太可惜了,毕竟考试时间很短。

Accepted    528kB   10ms    1176 B  G++
#define MAX_M 30261#include<stdio.h>#include<stdlib.h>const int num[10]={6,2,5,5,4,5,6,3,7,6};const int ten[8]={1,10,100,1000,10000,100000,1000000,10000000};int n,ans=0,sticks_sum,sum;int m=1,a[MAX_M][2];void dfs(int x,int dig,int sticks,int last){    if (sticks>n-4)        return;    for (int i=0;i<=9;i++)        dfs(x+i*ten[dig],dig+1,sticks+num[i],i);    if (last)    {        a[m][0]=x;        a[m][1]=sticks;        m++;    }}int compare(const void *e1,const void *e2){    return ((int *)e1)[1]-((int *)e2)[1];}int main(){    scanf("%d",&n);    a[0][0]=0;    a[0][1]=6;    for (int i=0;i<=9;i++)        dfs(i,1,num[i],i);    qsort(a,m,sizeof(int[2]),compare);    /*    freopen("output.txt","w",stdout);    for (int i=0;i<m;i++)        printf("%d %d\n",a[i][0],a[i][1]);    */    for (int i=0;i<m;i++)        for (int j=0;j<m;j++)        {            if (a[i][1]+a[j][1]>n-6)                break;            sum=a[i][0]+a[j][0];            sticks_sum=0;            if (sum==0)                sticks_sum=6;             while (sum)    1       {                sticks_sum+=num[sum%10];                sum/=10;            }            if (a[i][1]+a[j][1]+sticks_sum==n-4)            {                //printf("%d(%d)+%d(%d)=%d(%d)\n",a[i][0],a[i][1],                //  a[j][0],a[j][1],a[i][0]+a[j][0],sticks_sum);                 ans++;            }         }    printf("%d\n",ans);    return 0;}
0 0
原创粉丝点击