zoukankan      html  css  js  c++  java
  • UVa 10023

    http://uva.onlinejudge.org/index.php?option=com_onlinejudge&Itemid=8&page=show_problem&problem=964


    题目大意,给一个数y(1 <= y <= 10^1000),求 y 的开方,题目保证了y 是一个完全平方数,并且没有前导零或者空格,输入数据每个隔一行,输出数据每个隔一行。


    大数开方主要是三种方法,二分,牛顿迭代,手算开方,我写的是手算开方的,调试了半天终于可以正常地算出结果了,那时候没有注意到输出要有空行,而且最后一个数据后不能有空行,结果WA了两天。。。为什么不显示PE,差点WA得哭了。


    手算开方的原理是利用(10a + b)(10a + b)= 100 a^2 + 20ab + b^2,

    先把一个大整数从最低位开始分解成两个一节的。 eg. 12,34,56,78,90

    ①首先先看最前面一节,小于等于12的一个最大的平方数是9,先取a = 3,此时余数是3,将下一节加入余数,得到r = 3,34

    ②接下来求最大的 b 使得 20ab + b^2 <= 334, 这里先将a 代进去,得到b = 5,此时余数是 9

    ③此时需要将a 用 10a + b 取代,所以这时候a = 35,讲下一节加入r ,r = 9,56

    接着不断重复重复②和③这两个步骤。

    这边顺便再写两步,此时再去找最大的 b 使得 20ab + b^2 <= 956,将a = 35代入,求得 b = 1, 然后r = 2,55,然后 a = 351,将后一节加入r, r = 2,55,78.。。。。。


    上代码:

      1 #include<cmath>
      2 #include<cstdio>
      3 #include<cstring>
      4 #include<algorithm>
      5 using namespace std;
      6 const int MOD = 2;
      7 const int D_MOD = 100;
      8 const int MAXN = 1000 + 5;
      9 
     10 int n;
     11 char str[MAXN];
     12 
     13 int getInt(char *str, int len)
     14 {
     15     int res = 0;
     16 
     17     for(int i = 0; i < len; ++ i)
     18         res = res * 10 + (str[i] - '0');
     19 
     20     return res;
     21 }
     22 
     23 class BigNumber
     24 {
     25 public:
     26     int intLen;
     27     int decimal[MAXN];
     28 
     29     BigNumber()
     30     {
     31         this->intLen = 1;
     32         memset(this->decimal, 0, sizeof(this->decimal));
     33     }
     34 
     35     BigNumber(char *str)
     36     {
     37         //初始化
     38         this->intLen = 1;
     39         int intLen = (int)strlen(str);
     40         this->intLen = (intLen + MOD - 1) / MOD;
     41         memset(this->decimal, 0, sizeof(this->decimal));
     42 
     43         if(intLen & 1)
     44         {
     45             this->decimal[this->intLen - 1] = getInt(str, 1);
     46             ++str;
     47         }
     48         else
     49         {
     50             this->decimal[this->intLen - 1] = getInt(str, 2);
     51             str += 2;
     52         }
     53 
     54         for(int i = this->intLen - 2; i >= 0; -- i, str += 2)
     55             this->decimal[i] = getInt(str, 2);
     56     }
     57 
     58     bool operator > (const BigNumber &x) const
     59     {
     60         if(this->intLen == x.intLen)
     61             for(int i = x.intLen - 1; i >= 0; -- i)
     62                 if(this->decimal[i] != x.decimal[i])
     63                     return this->decimal[i] > x.decimal[i];
     64 
     65         return this->intLen > x.intLen;
     66     }
     67 
     68     bool operator == (const BigNumber &x) const
     69     {
     70         if(this->intLen == x.intLen)
     71         {
     72             for(int i = 0; i < x.intLen; ++ i)
     73                 if(this->decimal[i] != x.decimal[i])
     74                     return false;
     75 
     76             return true;
     77         }
     78 
     79         return (this->intLen == x.intLen);
     80     }
     81 
     82     //加上一个小于D_MOD的数
     83     BigNumber operator + (int x) const
     84     {
     85         int tt;
     86         BigNumber bg;
     87         bg.intLen = this->intLen;
     88 
     89         for(int i = 0; i < this->intLen; ++ i)
     90         {
     91             tt = this->decimal[i] + x;
     92             bg.decimal[i] = tt % D_MOD;
     93             x = tt / D_MOD;
     94         }
     95 
     96         if(x)
     97             bg.decimal[bg.intLen++] = x;
     98 
     99         return bg;
    100     }
    101 
    102     //保证了差为正数时才可调用
    103     BigNumber operator - (const BigNumber & x) const
    104     {
    105         BigNumber bg;
    106         bg.intLen = this->intLen;
    107 
    108         for(int i = 0; i < bg.intLen; ++ i)
    109             bg.decimal[i] = this->decimal[i] - x.decimal[i];
    110 
    111         for(int i = 0; i < bg.intLen - 1; ++ i)
    112             if(bg.decimal[i] < 0)
    113             {
    114                 --bg.decimal[i + 1];
    115                 bg.decimal[i] += D_MOD;
    116             }
    117 
    118         for(int i = bg.intLen - 1; i > 0; -- i)
    119             if(bg.decimal[i] == 0)
    120                 --bg.intLen;
    121             else
    122                 break;
    123 
    124         return bg;
    125     }
    126 
    127     //乘一个小于D_MOD的数
    128     BigNumber operator * (int x) const
    129     {
    130         BigNumber bg;
    131 
    132         if(x == 0)
    133             return bg;
    134 
    135         int tt, temp = 0;
    136         bg.intLen = this->intLen;
    137 
    138         for(int i = 0; i < this->intLen; ++ i)
    139         {
    140             tt = this->decimal[i] * x + temp;
    141             bg.decimal[i] = tt % D_MOD;
    142             temp = tt / D_MOD;
    143         }
    144 
    145         while(temp)
    146         {
    147             bg.decimal[bg.intLen++] = temp % D_MOD;
    148             temp /= D_MOD;
    149         }
    150 
    151         return bg;
    152     }
    153 
    154     //移位操作,乘以D_MOD
    155     void MoveOneStep()
    156     {
    157         for(int i = this->intLen - 1; i >= 0; -- i)
    158             this->decimal[i + 1] = this->decimal[i];
    159 
    160         if(this->decimal[this->intLen] != 0)
    161             ++this->intLen;
    162     }
    163 
    164     void OutPut()
    165     {
    166         printf("%d", this->decimal[this->intLen - 1]);
    167 
    168         for(int i = this->intLen - 2; i >= 0; -- i)
    169             printf("%02d", this->decimal[i]);
    170 
    171         putchar('
    ');
    172     }
    173 };
    174 
    175 int Find_b(const BigNumber &a, const BigNumber &r)
    176 {
    177     BigNumber temp;
    178 
    179     for(int b = 1; b < 10; ++ b)
    180     {
    181         temp = a * (20 * b) + b * b;
    182 
    183         if(temp > r)
    184             return b - 1;
    185         else if(r == temp)
    186             return b;
    187     }
    188 
    189     return 9;
    190 }
    191 
    192 void Sqrt(const BigNumber &x)
    193 {
    194     BigNumber a, r;
    195     int b, tLen = x.intLen - 1;
    196     a.decimal[0] = (int)sqrt(x.decimal[tLen] + 0.5);
    197     r.decimal[0] = x.decimal[tLen--] - a.decimal[a.intLen - 1] * a.decimal[a.intLen - 1];
    198 
    199     while(tLen >= 0)
    200     {
    201         r.MoveOneStep();
    202         r.decimal[0] = x.decimal[tLen--];
    203         b = Find_b(a, r);
    204         r = r - (a * (20 * b) + b * b);
    205         a = a * 10 + b;
    206     }
    207 
    208     a.OutPut();
    209 }
    210 
    211 int main()
    212 {
    213     int T;
    214     scanf("%d
    ", &T);
    215 
    216     while(T--)
    217     {
    218         gets(str);
    219         BigNumber x(str);
    220         Sqrt(x);
    221         getchar();
    222 
    223         if(T)
    224             putchar('
    ');
    225     }
    226 
    227     return 0;
    228 }
    View Code


  • 相关阅读:
    BZOJ 1069 最大土地面积
    BZOJ 1059 矩阵游戏
    BZOJ 3570 动物园
    Luogu 3934 Nephren Ruq Insania
    Luogu 3233 [HNOI2014]世界树
    CF613D Kingdom and its Cities
    Luogu 4001 [BJOI2006]狼抓兔子
    Luogu 2824 [HEOI2016/TJOI2016]排序
    POJ 3463 Sightseeing
    Luogu 2495 [SDOI2011]消耗战
  • 原文地址:https://www.cnblogs.com/tank39/p/3911399.html
Copyright © 2011-2022 走看看