题意:给定一个由数字,A-Z,a-z组成的字符串,求最小的进位制n,使得这个字符串在这个进位制下是正确的数,且这个数能被n-1整除。
思路:首先可以求出正确进制的下界,也就是找到输入串中出现最大的“数字”是多少。然后从这个下界往上枚举即可。这里需要注意,将数字表示成
a(k)*n^(k-1) + a(k-1)*n^(k-2)+...+a(1)的形式(a(k)表示数的最高位),这个东西要能被n-1整除才行。那么看第一项,n^(k-1)=n^(k-2)*(n-1+1)=(n-1)*n^(k-2)+n^(k-2),前面前一项肯定能被n-1整除,后面那一项归入n^(k-2)项,如此下去发现需要确定的就是a(k)+a(k-1)+...+a(1)是否能被n-1整除。
#include <cstdio>
#include <cstring>
using namespace std;
#define N 65537
char s[N];
int flag[300];
int main(){
while(scanf("%s",s) != EOF){
int i,j,sum=0,base = 1;
memset(flag,0,sizeof(flag));
for(i = 0;s[i];i++)
flag[s[i]]++;
for(i = '0';i<='9';i++)
if(flag[i]){
base = i-'0'+1;
sum += flag[i]*(i-'0');
}
for(i = 'A';i<='Z';i++)
if(flag[i]){
base = i-'A'+10+1;
sum += flag[i]*(i-'A'+10);
}
for(i = 'a';i<='z';i++)
if(flag[i]){
base = i-'a'+36+1;
sum += flag[i]*(i-'a'+36);
}
for(;base<=62;base++){
// printf("%d %d\n",sum,base);
if(sum % (base-1) == 0)
break;
}
if(base > 62)
printf("such number is impossible!\n");
else
printf("%d\n",base);
}
return 0;
}