题目描述
霍纳(Horner)规则是一种将一元n次多项式的求值问题转化为n个一次式的算法。采用最小的乘法运算策略,用于求多项式A(x)=a0+a1x+a2x2+...+an−1xn−1+anxn在x处的值,转化为A(x)=a0+x(a1+x(a2+...+x(an−1+xan)⋅⋅⋅))。其伪代码如下:
y = 0
for i = n downto 0
y = ai + x * y
给一个8进制数,这个数很大,他的长度甚至可以达到1e6(即10的6次方)。请输出这个数十进制意义下对1e9+7取模(即取余数)的结果。
输入
第一个数为数据组数n。n <= 10。
每组数据包括一行,一个大整数S,表示给定的8进制数x。S在字符串意义下长度不超过1e6。
输出
对于每组数据,输出一行,为其十进制下对1e9+7取模的值。
输入样例
2
22
2222222222222222222
输出样例
18
733442737
思路
本题是一个简单的霍纳法则的应用类问题。
霍纳法则:
多项式
A(x)=a0+a1x+a2x2+...+an−1xn−1+anxn
在x处的值,转化为
A(x)=a0+x(a1+x(a2+...+x(an−1+xan)⋅⋅⋅))
由于非十进制数向十进制数的转换可以按位转换再相加,刚好和霍纳法则的形式相近,使用霍纳法则可以大大降低程序的时间复杂度。
本题的数据由于位数太长,在读入的时候需要用字符串读入,在运算的时候,用-'0'的方法,累位转化为数字即可。
说明一下,由于待计算的数字是按照数字的高位存储在数组的低位中的顺序存储的,因此刚好符合霍纳法则中,从最内层括号向外层层计算的顺序。
代码中的x可变为1-9中的任意数字,因此原代码可转化为任何进制数转化为十进制数的代码。
参考代码
1 #include<stdio.h> 2 #include<string.h> 3 #define Mod 1000000007 4 #define MAXN 1000002 5 char s[MAXN]; 6 int main() 7 { 8 int x = 8; 9 int n; 10 scanf("%d",&n); 11 while(n--){ 12 scanf("%s",s); 13 int len = strlen(s); 14 int i; 15 long long res = 0; 16 for(i = 0;i < len;i++) 17 res = (res * x +(s[i] - '0')) % Mod; 18 printf("%lld\n",res); 19 } 20 21 return 0; 22 }