[pieces]洛谷P1601,P1303自我总结

P1601

  • 不要尝试对字符串作倒序。C语言的难点就在于此。既然对C++相对熟悉不要随意跳出去。
  • string的擦除更改意味着更多的构造和析构。不如建立一个新的字符串进行存储。而且这个500位对于空间复杂度来说根本不是事。500位对应着1 ms之差。
  • 此题的类型转换要注意:高位类型和低位类型运算的时候,为避免精度损失,是将低位转化高位类型。因而字符型和整型运算的时候,尽量在关键节点处使用转换。如果不转换,那么最后以数字写入string会乱码(我也不知道为什么)
  • 循环的选取:while是断言型,for是次数型。在某种程度上说,while更接近自然语言地表达程序意义,for更接近机器。
  • 成员函数调用很浪费时间:代码中的两线之间的段落换掉,时间会大大降低1000位对应10 ms。这里由于频繁调用string size,所以繁费了大量时间。这一条或许可以对应“发挥寄存器的功用”。
  • O2优化在VSCode当中没有对变量初始值的优化选项。上洛谷或许好用。所以要注意初始化。
#pragma GCC optimize(2)
#include <bits/stdc++.h>
using namespace std;
int main()
{
#ifdef _LOC_
    freopen("1.in", "r", stdin);
    freopen("1.out", "w", stdout);
#endif
    string a;
    string b;
    cin >> a >> b;
//--------------------------------------------------------------------------
    if (a.size() > b.size())
        while (a.size() > b.size())//大量地取用成员会很浪费时间。1000次约10ms
            b = "0" + b;
    else
        while (a.size() < b.size())
            a = "0" + a;
//--------------------------------------------------------------------------

    int bitup, tmp;
    for (int i = a.size() - 1; i >= 0; i--)
    {
        tmp = (a[i] - '0') + (b[i] - '0') + bitup;
        a[i] = char(tmp % 10 + '0');
        bitup = tmp / 10;
    }
    if (bitup)
        cout << bitup;
    cout << a;
#ifdef _LOC_
    fclose(stdin);
    fclose(stdout);
#endif
    return 0;
}

//一个更好的答案,采用了函数式。
string add(string str1,string str2)//高精度加法
{
    string str;
    int len1=str1.length();
    int len2=str2.length();
    //前面补0,弄成长度相同
    if(len1<len2)
    {
        for(int i=1;i<=len2-len1;i++)
           str1="0"+str1;
    }
    else
    {
        for(int i=1;i<=len1-len2;i++)
           str2="0"+str2;
    }
    len1=str1.length();
    int cf=0;
    int temp;
    for(int i=len1-1;i>=0;i--)
    {
        temp=str1[i]-'0'+str2[i]-'0'+cf;
        cf=temp/10;
        temp%=10;
        str=char(temp+'0')+str;
    }
    if(cf!=0)  str=char(cf+'0')+str;
    return str;
}

P1303

  • 两种进位的比较
    for (int i = 1; i <= len; i++)
    {
        na = (a[len - i] - '0');
        for (int j = 1; j <= len; j++)
        {
            tmp = na * (b[len - j] - '0');
            k = len * 2 - i - j + 1;
            ans[k-1] += (ans[k] += tmp)/10;//三次运算
            ans[k] %= 10;//一次运算
        }
    }
//---------------------------------------------------------------------------
    for (int i = 1; i <= len; i++)
    {
        int na = (a[len - i] - '0');
        for (int j = 1; j <= len; j++)
        {
            tmp = na * (b[len - j] - '0');
            int k = len * 2 - i - j + 1;
            while (tmp != 0)//两个循环,三次判断,很浪费时间
            {
                ans[k] += tmp % 10;//每次都对单独的一位进行判定操作,即加进位
                (tmp /= 10) += (ans[k] / 10);//进位
                ans[k--] %= 10;//取模
                if (k < 0)		//这样就做了六次运算。同时加上多的这个判断,就很浪费时间
                    break;
            }
        }

  • 另一个优化:去掉前导零时留一位,就免去了对结果为0的特判。
    for (; i < l-1; i++)
        if (ans[i])
            break;
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值