【洛谷】训练场_高精度算法

今天练习的是高精度算法篇:

 

前三题都是关于高精度算法的加法减法乘法运算模板题,推荐以下博客学习:

https://blog.csdn.net/fanyun_01/article/details/79967170

 

既然AC了前三题,那么下面两题应该也不成问题了:

 

P1255数楼梯

题意:

楼梯上有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 }
AC代码

 

下一题:

P1604 B进制星球

题意:

输入一个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 }
AC代码

 

最后小结:

高精度的加减乘法的思维感觉就像小学算数时列的竖式,有这样的思想就很好办。

非常感谢前辈们的学习笔记!

posted on 2019-05-05 20:50  Ayasan  阅读(270)  评论(0编辑  收藏  举报