Input
Input is given from Standard Input in the following format:
X
M
Output
Print the answer.
Sample Input 1
22
10
Sample Output 1
2
Sample Input 2
999
1500
Sample Output 2
3
Sample Input 3
100000000000000000000000000000000000000000000000000000000000
1000000000000000000
Sample Output 3
1
题目大意
给定一个字符串X,X由‘0’~‘9’组成,设d是X中最大的数字,求有多少个不同的整数<=M,整数有以下要求:
- 是一个n进制数(n>=d+1)
- 这个数的n进制表示是X
- n进制对应的十进制数>=M
分析
如果X只包含一个字符,由于进制数大于X中的最大数字,因此无论X是几进制,对应的十进制数大小不变,这种情况需要特殊判断;如果X的长度大于1,X的进制数越大,对应的十进制数越大,不同的进制数对应不同的十进制数,因此只需找有多少种进制满足条件,由于随着进制数的增大,对应的十进制数是递增的,因此可以用二分法快速确定边界。
AC代码
#include <bits/stdc++.h>
using namespace std;
typedef unsigned long long ull;
typedef __int128 ll;
string x;
ull m;
bool check(ull mid)
{
ll ans=0;
int flag=1;
for(int i=0;i<x.size();i++)
{
ans=ans*mid+ll(x[i]-'0');
if(ans>m)
{
flag=0;
break;
}
}
return flag;
}
int main()
{
char c='0';
cin>>x>>m;
for(int i=0;i<x.size();i++)
{
c=max(c,x[i]);
}
ull t=c-'0';
if(x.size()==1)
{
if(t-1<=m) cout<<1<<endl;
else cout<<0<<endl;
}
else
{
ull l=0,r=1e18;
while(l<r)
{
ull mid=(l+r+1)>>1;
if(check(mid)) l=mid;
else r=mid-1;
}
if(l<t) cout<<0<<endl;
else cout<<l-t<<endl;
}
return 0;
}
注意
在check()函数中,ans的值可能超出unsigned long long的范围,要使用__int128