51nod 1166 K进制下的大数 (快速幂)

Posted xingkongyihao

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了51nod 1166 K进制下的大数 (快速幂)相关的知识,希望对你有一定的参考价值。

有一个字符串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。
Input示例
A1A
Output示例
22


其实可以当成快速幂来算,由于ab%mod ==  ((a%mod)(b%mod))%mod,(a+b)%mod == (a%mod + b%mod)%mod,比如A1A用22进制进制表示时为10*22^2+1*22+10*22^0 ,设当前为k进制,其实整个数模k-1为∑s[i]*pow(k,len-i-1) %(k-1)。这样就转换成快速幂了。

 1 #include <bits/stdc++.h>
 2 using namespace std;
 3 const int N = 1e5+10;
 4 char s[N];
 5 int len;
 6 map<char,int> mp;
 7 int pow_mod(int x, int n, int mod) {
 8     int y = 1;
 9     while(n) {
10         if(n&1) y = y*x%mod;
11         x = x*x%mod;
12         n >>= 1;
13     }
14     return y;
15 }
16 bool ok(int k) {
17     int ans = 0;
18     for(int i = 0; i < len; i ++) {
19         ans += pow_mod(k,(len-i-1)%(k-1),k-1)*mp[s[i]]%(k-1);
20     }
21     ans %= (k-1);
22     return ans == 0;
23 }
24 int main() {
25     cin >> s;
26     len = strlen(s);
27     for(int i = 0; i < 10; i ++) mp[0+i] = i;
28     for(int i = 0; i < 26; i ++) mp[A+i] = i+10;
29     int k = 2;
30     for(int i = 0; i < len; i ++) k = max(k, mp[s[i]]);
31     for( ++ k; k <= 36; k ++) {
32         if(ok(k)) return 0*printf("%d
",k);
33     }
34     printf("No Solution
");
35     return 0;
36 }

 

以上是关于51nod 1166 K进制下的大数 (快速幂)的主要内容,如果未能解决你的问题,请参考以下文章

51NOD 1116 K进制下的大数(字符串取模 + 枚举)

51nod 1166 大数开平方(高精度+牛顿迭代法)

51nod 1004 n^n的末位数字快速幂

快速幂

51Nod 1004 n^n的末位数字(日常复习快速幂,莫名的有毒,卡mod值)

51nod 1013快速幂 + 费马小定理