今天练习的是高精度算法篇:
前三题都是关于高精度算法的加法、减法与乘法运算模板题,推荐以下博客学习:
https://blog.csdn.net/fanyun_01/article/details/79967170
既然AC了前三题,那么下面两题应该也不成问题了:
题意:
楼梯上有N阶,上一楼可以一步上一阶,也可以一步上二阶。
编一个程序,计算共有多少种不同的走法。
分析:
运用斐波那契数列的思想:
当N=1时,只有一种办法,就是走一阶;
当N=2时,有两种办法,①:两次有一阶;②:一次走两阶;
当N=3时,其办法数等于N=1时与N=2时的方法数的总和,因为当N=1时,下一步走2阶就达到第3级,当N=2时,下一步走1阶时就达到第3级;
然后以此类推……
因为N<=5000,用long long也会爆数据的,所以要用高精度的加法,只需要在模板的基础上增添string[]即可。
题目坑点在于测试点会测试N=0的情况,只需要特判以下N!=0就可以解决。
我这里使用了打表。
1 #include<iostream> 2 #include<cstdio> 3 #include<string> 4 #include<cstring> 5 using namespace std; 6 7 string str[5005]; 8 int a[5000], b[5000]; 9 int N; 10 11 void solve() 12 { 13 str[1] = "1"; str[2] = "2"; 14 for(int x = 3; x <= 5000; x++){ // 高精度的加法运算 15 str[x] = ""; 16 memset(a, 0, sizeof(a)); 17 memset(b, 0, sizeof(b)); 18 a[0] = str[x-2].size(); 19 b[0] = str[x-1].size(); 20 for(int i = 1; i <= a[0]; i++) 21 a[i] = str[x-2][a[0]-i] - '0'; 22 for(int i = 1; i <= b[0]; i++) 23 b[i] = str[x-1][b[0]-i] - '0'; 24 25 int len = a[0] > b[0] ? a[0] : b[0]; 26 for(int i = 1; i <= len; i++){ 27 a[i] += b[i]; 28 a[i+1] += a[i] / 10; 29 a[i] %= 10; 30 } 31 len++; 32 while(a[len] == 0 && len > 1) len--; 33 for(int i = len; i >= 1; i--){ 34 str[x] += a[i] + '0'; 35 } 36 } 37 } 38 39 int main() 40 { 41 solve(); 42 while(cin >> N){ 43 if(N == 0) cout << 0 << endl; 44 else cout << str[N] << endl; 45 } 46 return 0; 47 }
下一题:
题意:
输入一个B,表示接下来你输入的两个数字的以及两数之和的进制。
分析:
高精度加法运算,只需要在原先思维(10进制)的基础上增加一个B代表B进制,解决字符串上0~9与A~Z的初始化与输出时的转化就很好解决。
1 #include<iostream> 2 #include<cstdio> 3 #include<string> 4 #include<cstring> 5 using namespace std; 6 7 string str1, str2; 8 int a[2002], b[2003]; 9 int B; 10 11 int main() 12 { 13 while(cin >> B){ 14 cin >> str1 >> str2; 15 memset(a, 0, sizeof(a)); 16 memset(b, 0, sizeof(b)); 17 a[0] = str1.size(); 18 b[0] = str2.size(); 19 for(int i = 1; i <= a[0]; i++){ 20 if(str1[a[0]-i] >= 'A' && str1[a[0]-i] <= 'Z') 21 a[i] = str1[a[0]-i] - 'A' + 10; 22 else 23 a[i] = str1[a[0]-i] - '0'; 24 } 25 for(int i = 1; i <= b[0]; i++){ 26 if(str2[b[0]-i] >= 'A' && str2[b[0]-i] <= 'Z') 27 b[i] = str2[b[0]-i] - 'A' + 10; 28 else 29 b[i] = str2[b[0]-i] - '0'; 30 } 31 32 int len = a[0] > b[0] ? a[0] : b[0]; 33 for(int i = 1; i <= len; i++){ 34 a[i] += b[i]; 35 a[i+1] += a[i] / B; 36 a[i] %= B; 37 } 38 len++; 39 while(a[len] == 0 && len > 1) len--; 40 for(int i = len; i >= 1; i--){ 41 if(a[i] > 9) 42 cout << (char)(a[i]+'A'-10); 43 else 44 cout << a[i]; 45 } 46 cout << endl; 47 } 48 return 0; 49 }
最后小结:
高精度的加减乘法的思维感觉就像小学算数时列的竖式,有这样的思想就很好办。
非常感谢前辈们的学习笔记!