HDU-4249-A Famous Equation(DP)

本文探讨了一种解决数学等式中缺失数字的编程算法,具体描述了一个等式,其中部分数字被替换为问号。通过动态规划的方法,文章详细解释了如何计算并确定所有可能的解决方案的数量。此算法适用于处理任意长度不超过9的等式,并且能够准确处理前导零、进位以及其他边界情况。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

Problem Description
Mr. B writes an addition equation such as 123+321=444 on the blackboard after class. Mr. G removes some of the digits and makes it look like “1?3+??1=44?”. Here “?” denotes removed digits. After Mr. B realizes some digits are missing, he wants to recover them. Unfortunately, there may be more than one way to complete the equation. For example “1?3+??1=44?” can be completed to “123+321=444” , “143+301=444” and many other possible solutions. Your job is to determine the number of different possible solutions.
 

Input
Each test case describes a single line with an equation like a+b=c which contains exactly one plus sign “+” and one equal sign “=” with some question mark “?” represent missing digits. You may assume a, b and c are non-negative integers, and the length of each number is no more than 9. In the other words, the equation will contain three integers less than 1,000,000,000.
 

Output
For each test case, display a single line with its case number and the number of possible solutions to recover the equation.
 

Sample Input
  
  
7+1?=1? ?1+?1=22
 

Sample Output
  
  
Case 1: 3 Case 2: 1
Hint
There are three solutions for the first case: 7+10=17, 7+11=18, 7+12=19 There is only one solution for the second case: 11+11=22 Note that 01+21=22 is not a valid solution because extra leading zeros are not allowed.
 

Source
 

思路:dp[i][0]表示从右往左第i位不进位的方法数,dp[i][1]表示进位的方法数。 坑点:①long long。②前导零。③1+1=2这种情况结果为1,加特判还WA了。④细节。

代码写得太挫,还是贴上来吧。。。

#include<stdio.h>
#include<string.h>

char a[50],b[50],c[50],s[100];
long long dp[10][2];

int main()
{
    int la,lb,lc,i,j,k,now,p,q,jp,jq,cas=1;

    while(~scanf("%s",s))
    {
        for(i=0;s[i];i++) if(s[i]=='+' || s[i]=='=') s[i]=' ';

        sscanf(s,"%s%s%s",a,b,c);

        la=strlen(a)-1;
        lb=strlen(b)-1;
        lc=strlen(c)-1;

        dp[0][0]=1;
        dp[0][1]=0;

        now=1;

        while(la>=0 || lb>=0 || lc>=0)
        {
            p=q=jp=jq=0;

            if(la>=0 && a[la]=='?')
            {
                for(i=0;i<=9;i++)
                {
                    if(!la && now>1 && !i) continue;

                    if(lb>=0 && b[lb]=='?')
                    {
                        for(j=0;j<=9;j++)
                        {
                            if(!lb && now>1 && !j) continue;

                            if(lc>=0 && c[lc]=='?')
                            {
                                for(k=0;k<=9;k++)
                                {
                                    if(!lc && now>1 && !k) continue;

                                    if(i+j==k) p++;
                                    if(i+j==k-1) jp++;
                                    if(i+j-10==k) q++;
                                    if(i+j-10==k-1) jq++;
                                }
                            }
                            else
                            {
                                if(lc>=0) k=c[lc]-'0';
                                else k=0;

                                if(i+j==k) p++;
                                if(i+j==k-1) jp++;
                                if(i+j-10==k) q++;
                                if(i+j-10==k-1) jq++;
                            }
                        }
                    }
                    else
                    {
                        if(lb>=0) j=b[lb]-'0';
                        else j=0;

                        if(lc>=0 && c[lc]=='?')
                        {
                            for(k=0;k<=9;k++)
                            {
                                if(!lc && now>1 && !k) continue;

                                if(i+j==k) p++;
                                if(i+j==k-1) jp++;
                                if(i+j-10==k) q++;
                                if(i+j-10==k-1) jq++;
                            }
                        }
                        else
                        {
                            if(lc>=0) k=c[lc]-'0';
                            else k=0;

                            if(i+j==k) p++;
                            if(i+j==k-1) jp++;
                            if(i+j-10==k) q++;
                            if(i+j-10==k-1) jq++;
                        }
                    }
                }
            }
            else
            {
                if(la>=0) i=a[la]-'0';
                else i=0;

                if(lb>=0 && b[lb]=='?')
                {
                    for(j=0;j<=9;j++)
                    {
                        if(!lb && now>1 && !j) continue;

                        if(lc>=0 && c[lc]=='?')
                        {
                            for(k=0;k<=9;k++)
                            {
                                if(!lc && now>1 && !k) continue;

                                if(i+j==k) p++;
                                if(i+j==k-1) jp++;
                                if(i+j-10==k) q++;
                                if(i+j-10==k-1) jq++;
                            }
                        }
                        else
                        {
                            if(lc>=0) k=c[lc]-'0';
                            else k=0;

                            if(i+j==k) p++;
                            if(i+j==k-1) jp++;
                            if(i+j-10==k) q++;
                            if(i+j-10==k-1) jq++;
                        }
                    }
                }
                else
                {
                    if(lb>=0) j=b[lb]-'0';
                    else j=0;

                    if(lc>=0 && c[lc]=='?')
                    {
                        for(k=0;k<=9;k++)
                        {
                            if(!lc && now>1 && !k) continue;

                            if(i+j==k) p++;
                            if(i+j==k-1) jp++;
                            if(i+j-10==k) q++;
                            if(i+j-10==k-1) jq++;
                        }
                    }
                    else
                    {
                        if(lc>=0) k=c[lc]-'0';
                        else k=0;

                        if(i+j==k) p++;
                        if(i+j==k-1) jp++;
                        if(i+j-10==k) q++;
                        if(i+j-10==k-1) jq++;
                    }
                }
            }

            dp[now][0]=dp[now-1][0]*p+dp[now-1][1]*jp;
            dp[now][1]=dp[now-1][0]*q+dp[now-1][1]*jq;

            now++;

            la--;
            lb--;
            lc--;
        }

        printf("Case %d: %I64d\n",cas++,dp[now-1][0]);
    }
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值