AtCoder Beginner Contest 192 D - Base n

D - Base n

在这里插入图片描述
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

猜你喜欢

转载自blog.csdn.net/weixin_46155777/article/details/113921042