给定一个带通配符问号的数W,问号可以代表任意一个一位数字。
再给定一个整数X,和W具有同样的长度。
问有多少个整数符合W的形式并且比X大?
输入格式
多组数据,每组数据两行,第一行是W,第二行是X,它们长度相同。在[1..10]之间.
输出格式
每行一个整数表示结果。
输入样例
36?1?8
236428
8?3
910
?
5
输出样例
100
0
4
小记:这oj编译器 真是坑,坑了我2次,而且这题目 题意表述的也不是很清晰, 好在它的测试数据都能正确给出回应。前面两次都是没有在它那个编译器上编译通过就提交了。直接 哎呀,有点小错误!。。。 稍微将需要根据测试数据来改的争议点 改过来,就直接A了。
思路:这题其实还蛮简单的,主要是要想清楚,理清思路。
1、对于2个数一个用s1,一个用s2表示,s1是有通配符?的数字串,我们从第一个字符开始,两个字符串对应位置的字符进行对比
比较结果 > =
第一个? 9 - i1 1
第二个? 9 - i2 1
第三个? 9 - i3 1
...
这里 i1表示的是与那个?对应的数字。 这是大于i1可能数。i2,i3,in..类似
首先我们能知道的是每一次对比的结果只有3种,如果大于或小于就可以给出答案了,如果等于就还要继续比对。
现在我们从第一个字符开始比对,假设?的个数有cnt个,那么
如果第一个字符不是?,而s1的当前字符大于s2当前字符那么结果就是10^cnt,即10的cnt次方。
如果是小于,那么结果就是0
如果等于就继续。
当碰到第一个通配符?时,如上比对列表,先不管等于,那么就可以配上9 - i1个数字,那么不管后面还有多少个通配符?,每个?都可以任意取值,那么结果就要加上(9-i1)*10^(cnt-1)
cnt-1代表其后面还有通配符?的个数。
而对于等于,那么它就要看下一个通配符了,那么结果又要再加上(9-i2)*10^(cnt-2),而下一个通配符 也有一个等于,那结果又要加上(9-i3)*10^(cnt-3).
一直加到最后一个统配符为止,因为到那个通配符时,它不能等于,它等于的话,那么就和s2相等了,因此,最后一个通配符只能取大于的。
这样计算 将所有的结果相加便是结果,而这个有个前提,就是除了通配符?外,s1和s2的数字都相同。
上面那个相加和秦九韶算法类似,我们一个一个加,一步一步的乘。
(..(((9-i1)*10 + 9-i2)*10+9-i3)*10+...)*10+9-icnt :icnt 是第cnt个s1的?对应s2的数字
如若除了通配符?外,s1和s2的数字不同,那么还要加几个判断条件。
通配符?将s1分成了几块数字区域,若在其中某一块区域得到的结果是s1大于s2,那么若后面没有通配符了,那么在上面的结果上我们还要加上1,因为可以相等。
如果s1小于s2,则和上面结果一样。
如果是中间的某一块区域,那么因为我们是一步一步算的,如果s1大于s2,我们将前面的那些个通配符计算的结果加上1,然后后面的?就可以任意取值了,相乘一个10的后面还剩?的个数次方即可。
小于则不要加一了,直接乘以10的后面还剩?的个数次方就行了
如果是第一块,若s1大于s2,这个答案就是10的cnt次方。
若小于,则结果为0
还有一点就是如果一个通配符都没有,s1大于s2,答案就是1,否则是0
cmath都不准我用,cin也不行...
代码:
//#pragma comment(linker, "/STACK:102400000,102400000")
#include <string.h>
#include <stdio.h>
#include <iostream>
#include <vector>
#include <queue>
#include <algorithm>
//#include <cmath>
using namespace std;
#define MAX_ 100100
#define MAX 0x7fffffff
#define max(a,b) ((a>b)?(a):(b))
long long pow(long long x,long long y){
long long cnt = 1;
while(y){
cnt *= x;
y--;
}
return cnt;
}
int main() {
int i,s,t,c;
bool flag;
//string s1,s2;
char s1[MAX_],s2[MAX_];
while(~scanf("%s%s",s1,s2)) {
long long ans = 0, cnt = 0;
flag = false;
for(int i = 0; i < strlen(s1); ++i){
if(s1[i] == '?')cnt++,flag = true;
}
//cout<<cnt<<endl;
for(int i = 0; i < strlen(s1); ++i){
if(s1[i] == '?'){
ans = ans * 10 + 9 - (s2[i] - '0');
cnt--;
flag = true;
continue;
}
if(s1[i] > s2[i] ){
if(ans){
ans++;
ans *= pow(10,cnt);
}else
ans = pow(10,cnt);
flag = true;
break;
}
if(s1[i] < s2[i]){
if(ans){
ans *= pow(10,cnt);
}
break;
}
}
if(!flag)cout<<'0'<<endl;
else
cout<<ans<<endl;
}
return 0;
}