zoukankan      html  css  js  c++  java
  • 【SDOI2009】SuperGCD

    本题在洛谷上的链接:https://www.luogu.org/problemnew/show/P2152


    在做这道题之前,有位学长和我吹,他用10分钟两行代码就做完了。当时实在是吓到我了,自己做完这道题,好奇就去看看学长的代码,,,原来是Python。。。

    求最大公约数可以选择辗转相除法或者更相减损术,这道题最好是选择更相减损术,一个是相对较快,一个是适合高精度。

    简述一下更相减损术的过程,对于a和b,若其中只有一个是偶数,说明他们两个的最大公因数一定不是偶数,没有2这个因子,所以将其中的偶数除以2;若全是偶数,说明他们的最大公因数一定是偶数,一定有2这个因子,全部除以2,再将最终答案乘以2;若全为奇数,则用大数减小数。不断重复,直到a和b相等,就是答案。

    实际上,上面的算法严格意义上不是更相减损术,而是Stein算法,但二者都是通过减来求最大公约数,无非Stein算法多了只有一个数是偶数时的优化。

    另外,把高精度写成结构体确实方便,不过很容易出事,嗯,至少这次,需要写乘2和除以2的函数,如果重载运算符的话,就会因为一些语言的原因而超时。

     1 #include <cstdio>
     2 #include <iostream>
     3 #include <cstring>
     4 #include <string>
     5 
     6 using namespace std;
     7 
     8 const int maxn = 1e4 + 5;
     9 
    10 struct BigInteger {
    11     int num[maxn], len;
    12 
    13     BigInteger(string s = "") {
    14         memset(num, 0, sizeof(num));
    15         len = s.length();
    16         for (int i = 1; i <= len; ++i)
    17             num[i] = s[len - i] - '0';
    18     }
    19     
    20     bool operator < (const BigInteger& rhs) const {
    21         if (len != rhs.len) return len < rhs.len;
    22         else {
    23             for (int i = len; i >= 1; --i)
    24                 if (num[i] != rhs.num[i])
    25                     return num[i] < rhs.num[i];
    26         }
    27         return false;
    28     }
    29     
    30     bool operator == (const BigInteger& rhs) const {
    31         return !(*this < rhs) && !(rhs < *this);
    32     }
    33 
    34     void operator - (const BigInteger& rhs) {
    35         for (int i = 1; i <= len; ++i) {
    36             num[i] -= rhs.num[i];
    37             if (num[i] < 0) --num[i + 1], num[i] += 10;
    38         }
    39         while (!num[len] && len > 1) --len;
    40     }
    41 
    42     void mul2() {
    43         for (int i = 1; i <= len; ++i)
    44             num[i] *= 2;
    45         for (int i = 1; i <= len; ++i) {
    46             int j = i;
    47             while (num[j] > 9) {
    48                 num[j + 1] += num[j] / 10;
    49                 num[j++] %= 10;
    50             }
    51         }
    52         if (num[len + 1]) ++len;
    53     }
    54     void div2() {
    55         for (int i = len; i >= 1; --i) {
    56             num[i - 1] += num[i] % 2 * 10;
    57             num[i] /= 2;
    58         }
    59         while (!num[len] && len > 1) --len;
    60     }
    61 
    62     void print() {
    63         for (int i = len; i >= 1; --i)
    64             printf("%d", num[i]);
    65     }
    66 } a, b;
    67 
    68 string sa, sb;
    69 
    70 int main() {
    71     long long ans = 0;
    72     cin >> sa >> sb;
    73     a = BigInteger(sa), b = BigInteger(sb);
    74     while (!(a == b)) {
    75         if (a < b) swap(a, b);
    76         if (a.num[1] % 2 == 0 && b.num[1] % 2)
    77             a.div2();
    78         else if (b.num[1] % 2 == 0 && a.num[1] % 2)
    79             b.div2();
    80         else if (a.num[1] % 2 == 0 && b.num[1] % 2 == 0) {
    81             a.div2();
    82             b.div2();
    83             ++ans;
    84         } else a - b;
    85     }
    86     for (int i = 1; i <= ans; ++i)
    87         a.mul2();
    88     a.print();
    89     return 0;
    90 }
    AC代码
  • 相关阅读:
    strcpy的实现
    使用Highcharts生成柱状图
    使用Highcharts结合PHP与Mysql生成饼状图
    shopnc 学习笔记
    php中关于mysqli和mysql区别的一些知识点分析
    jquery捕获enter键 按enter键执行提交
    php在IE浏览器中保存SESSION
    ShopNC 商城系统开发经验分享第五篇: 缓存设计
    ShopNC 商城系统开发经验分享第二篇:ShopNC商城系统初步分析
    SHOPEX于SHOP++比较哪款更适合做二次开发,为什么?
  • 原文地址:https://www.cnblogs.com/Mr94Kevin/p/9825103.html
Copyright © 2011-2022 走看看