zoukankan      html  css  js  c++  java
  • 【洛谷】训练场_高精度算法

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

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

    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代码

    最后小结:

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

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

  • 相关阅读:
    *Delete Duplicate Emails
    Rising Temperature [MySQL]
    mysql链接表,connection string, federated engine
    谷歌在招什么样的人?
    用memcached的时候找key找不到,写了个命令来找找
    jna
    绕树三匝,无枝可依
    vm lxc
    linux proxy
    elisp
  • 原文地址:https://www.cnblogs.com/Ayanowww/p/10816173.html
Copyright © 2011-2022 走看看