A Famous Equation
http://acm.hdu.edu.cn/showproblem.php?pid=4249
7+1?=1? ?1+?1=22
Case 1: 3 Case 2: 1
题意:给一个包含'?'的等式,问这个等式可能有多少种
题解:dp[i][0]代表第i位满足条件且不进位的方法数,dp[i][1]代表第i位满足条件且进位的方法数。
然后枚举每个'?'可能的值,值的范围(以a为例)起点:a[i]=='?' 是 i不是最高位或者a只有个位 ?1:0
否 a[i]
终点:a[i]=='?' 是 9
否 a[i]
其他的就是各种判断了。
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
#define LL long long
LL dp[15][2];//dp[i][0]代表第i位满足条件且不进位的方法数,dp[i][1]代表第i位满足条件且进位的方法数
int a[15],b[15],c[15];
char s[50];
int al,bl,cl;
int main()
{
for(int l,cas=1;~scanf("%s",s);++cas)
{
al=bl=cl=0;
memset(dp,0,sizeof(dp));
//下面的清零很重要啊,因为这个一直WA...
memset(a,0,sizeof(a));
memset(b,0,sizeof(b));
memset(c,0,sizeof(c));
for(l=0;s[l]!='+';++l)
{
if(s[l]=='?') a[al++]=-1;
else a[al++]=s[l]-'0';
}
for(l=l+1;s[l]!='=';++l)
{
if(s[l]=='?') b[bl++]=-1;
else b[bl++]=s[l]-'0';
}
for(l=l+1;l<strlen(s);++l)
{
if(s[l]=='?') c[cl++]=-1;
else c[cl++]=s[l]-'0';
}
//a,b有一个的数字长度大于c
if(cl<bl||cl<al)
{
printf("Case %d: 0\n",cas);
continue;
}
reverse(a,a+al);
reverse(b,b+bl);
reverse(c,c+cl);
for(int i=0;i<cl;++i)
for(int j=(a[i]<0?((i<al-1||al==1)?0:1):(a[i]));j<=(a[i]<0?9:a[i]);++j)
for(int k=(b[i]<0?((i<bl-1||bl==1)?0:1):(b[i]));k<=(b[i]<0?9:b[i]);++k)
{
LL add;
if((c[i]<0||((j+k+1)%10==c[i])))
//上一位进位的情况
{
add=(i>0?dp[i-1][1]:0);
if(j+k+1>=10) dp[i][1]+=add;
else dp[i][0]+=add;
}
if((c[i]<0&&(i!=cl-1))||(c[i]<0&&(i==cl-1)&&(j+k>0))||(cl==1&&c[i]<0)||((j+k)%10==c[i]))
//上一位没有进位的情况
{
add=(i>0?dp[i-1][0]:1);
if(j+k>=10) dp[i][1]+=add;
else dp[i][0]+=add;
}
}
printf("Case %d: %I64d\n",cas,dp[cl-1][0]);
}
return 0;
}

本文探讨了一个含有问号的数学等式的解决方法,通过动态规划算法计算等式两边数字组合的可能性,旨在找到所有可能的解决方案。具体步骤包括初始化动态规划表,根据等式中的数字和问号进行迭代计算,最终确定满足条件的所有可能性。

被折叠的 条评论
为什么被折叠?



