写在前面:仅为个人代码/总结,未必标准,仅供参考!如有错误,还望指出交流,共同进步!
带通配符的数
【问题描述】给定一个可以带通配符问号的正整数W,问号可以代表任意一个一位数字。再给定一个正整数X,和W具有同样的长度。问有多少个整数符合W的形式并且比X大?
【输入形式】多组数据,每组数据两行,第一行是W,第二行是X,它们长度相同,在[1…10]之间。
【输出形式】每行一个整数表示结果。
【样例输入】
36?1?8
236428
8?3
910
?
5
【样例输出】
100
0
4
【思路】
①当第一个’?‘前面的某一位数大于对比数的相应位置的数字而该位数为第一位或其前面的数都等于对比数相应位置上的数时,可直接计算,为‘?’的个数作为幂,计算10的幂。若小
②当第一个’?‘前面的某一位数小于对比数的相应位置的数字而该位数为第一位或其前面的数都等于对比数相应位置上的数时,可直接输出零。
③当第一个‘?’前面的所有数都与对比数相应位置的数相等时,则分为两种情况,第一种为‘?’取大于对比数中对应位置的数的数,则通过①的方法计算,第二种为’?'取与对比数中对应位置的数相等的数,然后通过递归继续判断计算接下来的‘?’情况。最后两者结果相加。
【示例代码】
//递归
#include <bits/stdc++.h>
using namespace std;
int Pow(int n,int m)
{
int res=1;
for(int i=0;i<m;i++)
{
res*=n;
}
return res;
}
double result(char ch1[],char ch2[],int len,int i,int sum,int a[])
{
double res=0;
res+=(57-ch2[i])*Pow(10,a[i]);
sum++;
for(int j=i+1;j<len;j++)
{
if(ch1[j]=='?'&&sum==j)
{
res+=result(ch1,ch2,len,j,sum,a);
break;
}
else if(ch1[j]<ch2[j])
{
break;
}
else if(ch1[j]==ch2[j])
{
sum++;
}
else if(ch1[j]>ch2[j])
{
res+=Pow(10,a[j]);
break;
}
}
return res;
}
int main()
{
char ch1[10],ch2[10];
while(cin>>ch1>>ch2)
{
int len=strlen(ch1);
if(len==1&&ch1[0]=='?')//注意没有?的情况
{
cout<<57-ch2[0]<<endl;
continue;
}
int a[len],num=0;
for(int i=len-1;i>=0;i--)//用a存储每个元素后面?的个数
{
a[i]=num;
if(ch1[i]=='?')
{
num++;
}
}
int res=0,sum=0;//用sum记录某元素的前面元素相等个数
for(int i=0;i<len;i++)
{
if(ch1[i]=='?'&&sum==i)
{
res+=result(ch1,ch2,len,i,sum,a);//递归求解除?对应位置外其他位置元素相同的情况
break;
}
else if(ch1[i]>ch2[i])
{
if(sum==i)//若前面元素全部对应相等,则直接计算
{
res+=Pow(10,a[i]);
break;
}
}
else if(ch1[i]==ch2[i])
{
sum++;
}
else if(ch1[i]<ch2[i])
{
if(sum==i)
{break;}
}
}
cout<<res<<endl;
}
return 0;
}
/*
23?4?1?2
23643122
*/