HDU-4249-A Famous Equation(DP)

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

Fudan Local Programming Contest 2012

思路: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]);
    }
}

版权声明:本文博客原创文章,博客,未经同意,不得转载。

时间: 2024-08-09 13:17:18

HDU-4249-A Famous Equation(DP)的相关文章

HDOJ 4249 A Famous Equation DP

DP: DP[len][k][i][j] 再第len位,第一个数len位为i,第二个数len位为j,和的第len位为k 每一位可以从后面一位转移过来,可以进位也可以不进位 A Famous Equation Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) Total Submission(s): 500    Accepted Submission(s): 147 Proble

HDU 4249 A Famous Equation(数位DP)

题目链接:点击打开链接 思路:用d[i][a][b][c][is]表示当前到了第i位, 三个数的i位分别是a,b,c, 是否有进位 , 的方法数. 细节参见代码: #include<cstdio> #include<cstring> #include<algorithm> #include<iostream> #include<string> #include<vector> #include<stack> #includ

[ACM] hdu 4248 A Famous Stone Collector (DP+组合)

A Famous Stone Collector Problem Description Mr. B loves to play with colorful stones. There are n colors of stones in his collection. Two stones with the same color are indistinguishable. Mr. B would like to select some stones and arrange them in li

hdu 3555 Bomb(数位dp)

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=3555 题目大意:就是给你一个数n,判断从0到n有多少个数含有数字49...... 是不是觉得跟hdu2089很相似呀... 思路:跟hdu2089一样的,注意给出的数比较大,所以这儿用__int64  .... code: #include<cstdio> #include<iostream> #include<cstring> #include<algorithm&

HDU 1231 最大连续子序列 DP题解

典型的DP题目,增加一个额外要求,输出子序列的开始和结尾的数值. 增加一个记录方法,nothing special. 记录最终ans的时候,同时记录开始和结尾下标: 更新当前最大值sum的时候,更新开始节点. const int MAX_N = 10001; long long arr[MAX_N]; int N, sta, end; long long getMaxSubs() { long long sum = 0, ans = LLONG_MIN; int ts = 0; for (int

[ACM] hdu 2089 不要62(数位Dp)

不要62 Time Limit: 1000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) Total Submission(s): 19043    Accepted Submission(s): 6442 Problem Description 杭州人称那些傻乎乎粘嗒嗒的人为62(音:laoer). 杭州交通管理局经常会扩充一些的士车牌照,新近出来一个好消息,以后上牌照,不再含有不吉利的数字了,这样一来,就

HDU 4901 The Romantic Hero(DP)

HDU 4901 The Romantic Hero 题目链接 题意:给定一个序列,要求找一个分界点,然后左边选一些数异或和,和右边选一些数且和相等,问有几种方法 思路:dp,从左往右和从右往左dp,求出异或和且的个数,然后找一个分界点,使得一边必须在分界点上,一边随意,然后根据乘法原理和加法原理计算 代码: #include <cstdio> #include <cstring> typedef __int64 ll; const int N = 1024; const int

HDU 1160 FatMouse&#39;s Speed DP题解

本题就先排序老鼠的重量,然后查找老鼠的速度的最长递增子序列,不过因为需要按原来的标号输出,故此需要使用struct把三个信息打包起来. 查找最长递增子序列使用动态规划法,基本的一维动态规划法了. 记录路径:只需要记录后继标号,就可以逐个输出了. #include <stdio.h> #include <algorithm> using namespace std; const int MAX_N = 1005; struct MouseSpeed { int id, w, s; b

HDU 2089 不要62(数位DP,三种姿势)

HDU 2089 不要62(数位DP,三种姿势) ACM 题目地址:HDU 2089 题意: 中文题意,不解释. 分析: 100w的数据,暴力打表能过 先初始化dp数组,表示前i位的三种情况,再进行推算 直接dfs,一遍搜一变记录,可能有不饥渴的全部算和饥渴的部分算情况,记录只能记录全部算(推荐看∑大的详细题解Orz) 代码: 1. 暴力 (以前写的) /* * Author: illuz <iilluzen[at]gmail.com> * File: 2089_bf.cpp * Create