• Very simple problem


    分析:使用的是构造新数字法进行不断构造,然后逼近每一位数字,然后使用c++徒手敲了240多行代码,竟然过了........................很有成就感。

    代码如下:

    ===============================================================================================================================

    #include<stdio.h>
    #include<algorithm>
    #include<vector>
    #include<iostream>
    #include<math.h>
    #include<string.h>
    using namespace std;
    
    const int MAXN = 2007;
    
    struct BigNum
    {///数值保存从0位开始
        int Size;///数的位数
        int num[MAXN];///数值,逆序保存
    
        BigNum(){
            Size=1;
            memset(num, false, sizeof(num));
        }
        void Cin()
        {
            char s[MAXN];
    
            scanf("%s", s);
            Size = strlen(s);
    
            for(int i=Size-1; i>=0; i--)
                num[i] = s[Size-i-1] - '0';
        }
        bool operator <= (const BigNum &b)const
        {
            if(Size > b.Size)return false;
            if(Size < b.Size)return true;
    
            for(int i=Size-1; i>=0; i--)
            {
                if(num[i] > b.num[i])return false;
                if(num[i] < b.num[i])return true;
            }
    
            return true;
        }
        void operator = (const BigNum &b)
        {
            Size = b.Size;
    
            for(int i=0; i<b.Size; i++)
                num[i] = b.num[i];
        }
        void operator = (const int &b)
        {
            int tem = b;
    
            if(b == 0)
                Size = 1;
            else
                Size = (int)(log10(tem)+0.00001)+1;
    
            for(int i=0; i<Size; i++)
            {
                num[i] = tem % 10;
                tem /= 10;
            }
        }
        BigNum operator <<(const int &k)const
        {
            BigNum tmp;
    
            for(int i=Size-1; i>=0; i--)
            {
                tmp.num[i+k] = num[i];
            }
            tmp.Size = Size + k;
    
            tmp.CarryBit();
    
            return tmp;
        }
        BigNum operator * (const BigNum &b)const
        {
            BigNum res;
    
            res.Size = Size + b.Size - 1;
    
            for(int i=0; i<b.Size; i++)
            for(int j=0; j<Size; j++)
            {
                res.num[i+j] += num[j] * b.num[i];
            }
    
            res.CarryBit();
    
            return res;
        }
        BigNum operator * (const int &b)const
        {
            BigNum res;
    
            res.Size = Size;
    
            for(int i=0; i<Size; i++)
            {
                res.num[i] = num[i] * b;
            }
    
            res.CarryBit();
    
            return res;
        }
        BigNum operator + (const BigNum &b)const
        {
            BigNum res;
            res.Size = max(b.Size, Size);
    
            for(int i=0; i<res.Size; i++)
                res.num[i] = num[i] + b.num[i];
            res.CarryBit();
    
            return res;
        }
        BigNum operator + (const int &b)const
        {
            BigNum res;
            res = b;
    
            res.Size = max(res.Size, Size);
    
            for(int i=0; i<res.Size; i++)
                res.num[i] += num[i];
            res.CarryBit();
    
            return res;
        }
        BigNum operator - (const BigNum &b)const
        {///b值小,先比较在进行相减
            BigNum res;
    
            res.Size = Size;
            for(int i=0; i<Size; i++)
            {
                if(i < b.Size)
                    res.num[i] = num[i] - b.num[i];
                else
                    res.num[i] = num[i];
            }
            res.CarryBit();
    
            return res;
        }
        void CarryBit()
        {///进位,注意减法的时候进位结果需要是非负数
            for(int i=0; i<Size; i++)
            {
                if(num[i] >= 10)
                {
                    if(i+1==Size)
                    {
                        num[i+1] = 0;
                        Size += 1;
                    }
    
                    num[i+1] += num[i]/10;
                    num[i] %= 10;
                }
                else if(num[i] < 0)
                {
                    num[i+1] -= 1;
                    num[i] += 10;
                }
            }
            while(Size > 1 && !num[Size-1])
                Size -= 1;
        }
        void Out()
        {
            for(int i=Size-1; i>=0; i--)
                printf("%d", num[i]);
            printf("
    ");
        }
    };
    int Find(const BigNum &a, BigNum &Mod)
    {
        int i;
        BigNum t;
    
        for(i=1; i<=9; i++)
        {
            t = (((a*2)<<1)+i) * i;
    
            if(t <= Mod)
                continue;
            break;
        }
    
        i--;
        t = (((a*2)<<1)+i) * i;
    
        Mod = Mod - t;
    
        return i;
    }
    BigNum Sqrt(const BigNum &a)
    {
        BigNum ans, Mod;
        int len=a.Size-1;
    
        if(a.Size % 2 == 0)
        {
            Mod = Mod + (a.num[len]*10+a.num[len-1]);
            len -= 2;
        }
        else
        {
            Mod = Mod + a.num[len];
            len -= 1;
        }
    
        ans = Find(ans, Mod);
    
        while(len > 0)
        {
            Mod = (Mod<<2) + (a.num[len]*10+a.num[len-1]);
            ans = (ans<<1) + Find(ans, Mod);
    
            len -= 2;
        }
    
        return ans;
    }
    
    int main()
    {
        BigNum a;
    
        a.Cin();
        a = Sqrt(a);
    
        a.Out();
    
        return 0;
    }
  • 相关阅读:
    洛谷 P1443 马的遍历
    括号序列 (自出水题)
    19年清北学堂冬令营游记
    计数排列(模板)
    全排列
    unique去重
    链表 模板+详解
    输入输出优化
    关于广/宽度优先搜索
    第四周 6.7-6.13
  • 原文地址:https://www.cnblogs.com/liuxin13/p/4814401.html
Copyright © 2020-2023  润新知