有一个字符串S,记录了一个大数,但不知这个大数是多少进制的,只知道这个数在K进制下是K - 1的倍数。现在由你来求出这个最小的进制K。
例如:给出的数是A1A,有A则最少也是11进制,然后发现A1A在22进制下等于4872,4872 mod 21 = 0,并且22是最小的,因此输出k = 22(大数的表示中A对应10,Z对应35)。
Input
输入大数对应的字符串S。S的长度小于10^5。
Output
输出对应的进制K,如果在2 - 36范围内没有找到对应的解,则输出No Solution。
Sample Input
A1A
Sample Output
22
//暴力穷举,从2到36,一个一个看
#include<stdio.h>
#include<string.h>
char s[100005];
int main()
{
int len,k,i,sum;
scanf("%s",s);
len=strlen(s);
for(k=2;k<=36;k++)
{
sum=0;
for(i=0;i<len;i++)
{
if(s[i]>='0'&&s[i]<='9')
{
if(k<=s[i]-'0')//k进制数,怎么可能有小于等于k的数
{
k=s[i]-'0';//由于K是一个for循环,从这break后会加1,也就满足有数字s[i]-'0'的K进制
break;
}
sum=(sum*k+(s[i]-'0'))%(k-1);//这个就是大数的取余法,这个下面我会介绍一下
}
else if(k<=s[i]-'A'+10)//这个就是字母的情况,和上面差不多
{
k=s[i]-'A'+10;
break;
}
else
sum=(sum*k+(s[i]-'A'+10))%(k-1);
}
if(sum==0&&i==len)//sum==0说明大数是(k-1)的倍数
{
printf("%d\n",k);
return 0;
}
}
printf("No Solution\n");
return 0;
}
/*大数取余:举个例子,183%3的过程可分为:
1. 1%3=1;
2. (1*10+8)%3=0;
3. (0*10+3)%3=0;
最后结果就是0了,当然了,* 10 是因为 我是以10进制举例的,如果是K进制,那就 * K吧*/