题目描述:
1116 K进制下的大数
有一个字符串S,记录了一个大数,但不知这个大数是多少进制的,只知道这个数在K进制下是K - 1的倍数。
现在由你来求出这个最小的进制K。
例如:给出的数是A1A,有A则最少也是11进制,然后发现A1A在22进制下等于4872,4872 mod 21 = 0,
并且22是最小的,因此输出k = 22(大数的表示中A对应10,Z对应35)。
输入
输入大数对应的字符串S。S的长度小于10^5。
输出
输出对应的进制K,如果在2 - 36范围内没有找到对应的解,则输出No Solution。
输入样例
A1A
输出样例
22
思路:
----------------------------------------类比九余数定理--------------------
例题:https://blog.csdn.net/ray0354315/article/details/53991199
介绍一下九余数定理
(a+b)%p = (a%p+b%p)%p;
(a-b)%p = (a%p-b%p)%p;
(a*b)%p = (a%p*b%p)%p;
(a^b)%p = ((a%p)^b)%p;
1234%9=(1%9*1000%9+2%9*100%9+3%9*10%9+4%9)%9=(1+2+3+4)%9;
出现这种状况的原因的是10的倍数对9取余为1,例如1000=9*111+1 , 100=9*11+1 , 10=9*1+1;
总结:一个整数模9的结果与这个整数的各位数字之和模9的结果相同
代码实现:
#include<bits/stdc++.h>
#define LL long long
using namespace std;
const int N=2e5+100;
map<char,int>MM;
bool judge(string str,int k,int len)
{
LL sum=0;
for(int i=0;i<len;++i)
sum+=MM[str[i]];
if(sum%(k-1)==0)return 1;
return 0;
}
int main()
{
for(int i=0;i<=9;++i)MM.insert(make_pair('0'+i,i));
for(int i=1;i<=26;++i)MM.insert(make_pair('A'+i-1,i+9));//进制数要再+1
string str;
while(cin>>str)
{
bool f=0;
int len=str.size();
int maxs=2;
for(int i=0;i<len;++i)
maxs=max(maxs,MM[str[i]]+1);
int ans=-1;
//cout<<maxs<<endl;
for(int i=maxs;i<=36;++i)
{
if(judge(str,i,len))
{
ans=i;
break;
}
else continue;
}
if(ans!=-1)printf("%d\n",ans);
else printf("No Solution\n");
}
return 0;
}
The end;