AtCoder Beginner Contest 192 D - Base n

D - Base n

Insert picture description here
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

Insert picture description here

Sample Input 2

999
1500

Sample Output 2

3

Insert picture description here

Sample Input 3

100000000000000000000000000000000000000000000000000000000000
1000000000000000000

Sample Output 3

1

Insert picture description here
General idea

Given a character string X, X consists of '0'~'9', and let d be the largest number in X, find the number of different integers <=M. The integers have the following requirements:

  • Is an n-ary number (n>=d+1)
  • The n-ary representation of this number is X
  • Decimal number corresponding to base n>=M

analysis

If X contains only one character, because the hexadecimal number is greater than the largest number in X, no matter how many hexadecimals X is, the size of the corresponding decimal number remains the same. In this case, special judgment is required; if the length of X is greater than 1, the value of X The larger the base number, the larger the corresponding decimal number. Different base numbers correspond to different decimal numbers. Therefore, you only need to find how many bases meet the conditions. As the base number increases, the corresponding decimal number It is incremental, so the dichotomy can be used to quickly determine the boundary.

AC code

#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;
}

note

In the check() function, the value of ans may exceed the range of unsigned long long, use __int128

Guess you like

Origin blog.csdn.net/weixin_46155777/article/details/113921042