当前位置: 首页 > wzjs >正文

米拓企业网站管理系统南京seo全网营销

米拓企业网站管理系统,南京seo全网营销,wordpress固定导航,辽阳网站制作高精度 前言高精度加法例题思路及代码solution 1(初阶版 40分)solution 2(完全体 AC) 高精度乘法例题思路及代码solution 1(TLE 但是代码很清晰)solution 1的问题solution 2(优化 AC&#xff09…

前言

前两天考完了csp认证,总的来说还算正常发挥 休息了两天给大家更一个蓝桥杯

这个高精度是啥东西 说白了就是我们一般的数据类型存储不了的数字进行运算
具体来说就是10…(此处省略500个0),即便是强如 long long 也是存不下的

那么解决办法是啥?不算了?
显然不是 我们可以模拟小学学到竖式来计算 我们来分别来具体看加减乘除

我这里用例题来呈现
具体的讲解视频我附在这里 讲的真的太好了 我感觉就算一点没学过算法也能听明白

高精度系列视频

高精度加法

例题

思路及代码

solution 1(初阶版 40分)

在这里插入图片描述

我的注释写的非常详细了 但是由于我没有对特殊情况做出处理导致才过了2个样例
这里样例比较少 但是大部分情况下代码是没问题的

#include <bits/stdc++.h>
using namespace std;
int main()
{string s1,s2;//对于string类型会自动初始化为空字符串//对于数组来说如果不对他初始化 他会是一个随机值int a1[110], a2[110], a3[110]={0};//最长是500位加上500位 结果最多是一个501位数 所以大小我们定义510肯定够了 a1 a2 a3分别保存逆序存放的数字和结果 //读入我们输入的数字存进字符串里面cin>>s1;cin>>s2;//将读入的数字逆序存放在数组里面//例如我们将123的1存到数组里面 它的位置就是//a1[s1.size()-1-0] for(int i=0;i<s1.size();i++){a1[s1.size()-i-1]=s1[i]-'0';//-i是因为倒序  -1是因为数组下标从0开始;}for(int i=0;i<s2.size();i++){a2[s2.size()-i-1]=s2[i]-'0';}//求出循环次数也就是我们模拟竖式相加的次数 而在加法中这个是由较大的数来决定的 这里不用考虑负数也就是字符串较长的数字int len=s1.size();if(s2.size()>s1.size()){len=s2.size();}//相加操作for(int i=0;i<len;i++){a3[i]=a1[i]+a2[i];}//满10进位for(int i=0;i<len;i++){if(a3[i]>10){a3[i+1]+=a3[i]/10;a3[i]=a3[i]%10;}}//逆序输出//因为我们一开始将数组置为0 所以我们只需要找到第一个不为0的点//就可以找到逆序输出的起点if(a3[len]!=0)//判断一下最高位置是不是0{len++;}for(int i=len-1;i>=0;i--){cout<<a3[i];}
}

solution 2(完全体 AC)

首先优化的点在于将上面代码中的对应相加和进位操作放在了一个循环里面

第二个就是比较重要的点 就是如果结果是0 我们需要只输出一个0 也就是说去掉前序位置上的所有0

#include <bits/stdc++.h>
using namespace std;int main() {std::ios::sync_with_stdio(false); // 提高输入输出效率std::cin.tie(NULL);string s1, s2;cin >> s1 >> s2;int a1[510] = {0}, a2[510] = {0}, a3[510] = {0};// 将字符串逆序存入数组for(int i = 0; i < s1.size(); i++) {a1[s1.size() - i - 1] = s1[i] - '0';}for(int i = 0; i < s2.size(); i++) {a2[s2.size() - i - 1] = s2[i] - '0';}// 求出最大长度int len = max(s1.size(), s2.size());// 相加并处理进位int carry = 0;for(int i = 0; i < len || carry; i++) {if(i < len) a3[i] += a1[i] + a2[i];if(a3[i] >= 10) {carry = a3[i] / 10;a3[i] %= 10;a3[i+1] += carry;} else {carry = 0;}}// 输出结果int start = len;while(start >= 0 && a3[start] == 0) start--;if(start == -1) cout << "0"; // 特殊情况:结果为0else {for(int i = start; i >= 0; i--) {cout << a3[i];}}return 0;
}

高精度乘法

例题

在这里插入图片描述
题目链接

思路及代码

solution 1(TLE 但是代码很清晰)


#include <bits/stdc++.h>
using namespace std;
//首先这是一道高精度乘法(而且是高精度乘以高精度)
//我们需要用其中一个数的每一位去乘以另外一个高精度数
//大体上的思路就是用两层循环来实现 内层循环a1外层循环a2
int main()
{//string s1=""可以不初始化 string类型默认初始化为空字符串string s1,s2;int a1[2010],a2[2010],a3[4020]={0};getline(cin,s1);getline(cin,s2);//逆序存放在数组当中for(int i=0;i<s1.size();i++){a1[i]=s1[s1.size()-i-1]-'0';}for(int j=0;j<s2.size();j++){a2[j]=s2[s2.size()-j-1]-'0';}for(int i=0;i<s2.size();i++){for(int j=0;j<s1.size();j++){//第一次a3[j+0]=a3[j+0]+a1[j]*a2[i]//第二次a3[j+1]=a3[j+1]+a1[j]*a2[i]//通过找规律我们可以知道我们每一轮的变化就是a3[j+i]=a3[j+i]+a1[j]*a2[i];//进位判断if(a3[j+i]>10){a3[j+i+1]+=a3[j+i]/10;//看看能进几a3[j+i]=a3[j+i]%10;}}}//完成相乘操作之后 我们就需要逆序输出一下a3//首先我们需要明确的就是一个200✖️200的结果不会超过400位数///也就是这两个长度之和int index=0;for(int i=s1.size()+s2.size();i>=0;i--){if(a3[i]!=0){index=i;//找到了起始下标break;}}for(int i=index;i>=0;i--){cout<<a3[i];}return 0;}

solution 1的问题


  1. 算法复杂度问题
  • 当前复杂度:你的代码使用了两层嵌套循环来实现高精度乘法,外层循环遍历 s2 的每一位,内层循环遍历 s1 的每一位。假设 s1s2 的长度分别为 mn,那么时间复杂度为 O(m × n)
  • 问题点:如果输入的字符串长度较大(例如接近 2000),则计算量会非常大,导致超时。

  1. 进位逻辑效率问题
  • 当前实现:在每次相乘后立即进行进位操作:

    if(a3[j+i] > 10) {a3[j+i+1] += a3[j+i] / 10;a3[j+i] = a3[j+i] % 10;
    }
    

    这种方式会在每次相乘后都检查是否需要进位,增加了不必要的开销。

  • 优化方法:可以先完成所有乘法操作,最后统一处理进位。这样可以减少重复的进位判断。


  1. 输出部分的效率问题
  • 当前实现

    for(int i = s1.size() + s2.size(); i >= 0; i--) {if(a3[i] != 0) {index = i; // 找到起始下标break;}
    }
    for(int i = index; i >= 0; i--) {cout << a3[i];
    }
    

    使用了两个循环来找到第一个非零位并逆序输出结果。

  • 优化方法:可以通过一次循环完成查找和输出,减少冗余操作。


  1. 输入方式的问题
  • 当前实现

    getline(cin, s1);
    getline(cin, s2);
    

    使用 getline 读取输入字符串,虽然功能正确,但在某些评测环境中可能会比 cin 稍慢。

  • 优化方法:如果输入不包含空格,可以直接使用 cin 提高效率。


solution 2(优化 AC)

#include <bits/stdc++.h>
using namespace std;int main() {ios::sync_with_stdio(false); // 不用管就是 提高输入输出效率cin.tie(NULL);string s1, s2;cin >> s1 >> s2; // 使用 cin 提高效率int a1[2010] = {0}, a2[2010] = {0}, a3[4020] = {0};// 将字符串逆序存入数组for(int i = 0; i < s1.size(); i++) {a1[i] = s1[s1.size() - i - 1] - '0';}for(int i = 0; i < s2.size(); i++) {a2[i] = s2[s2.size() - i - 1] - '0';}// 高精度乘法for(int i = 0; i < s2.size(); i++) {for(int j = 0; j < s1.size(); j++) {a3[i + j] += a1[j] * a2[i]; // 先累加结果}}// 统一处理进位for(int i = 0; i < s1.size() + s2.size(); i++) {if(a3[i] >= 10) {a3[i + 1] += a3[i] / 10;a3[i] %= 10;}}// 输出结果int start = s1.size() + s2.size();while(start > 0 && a3[start] == 0) start--; // 去掉前导零if(start == -1) cout << "0"; // 特殊情况:结果为0else {for(int i = start; i >= 0; i--) {cout << a3[i];}}return 0;
}

高精度减法

例题

在这里插入图片描述

题目链接

代码及思路

solution 1 (90分)

应该是对于结果正好为0的时候没有特判 补一下

#include <bits/stdc++.h>
using namespace std;
int main()
{string s1,s2;cin>>s1;cin>>s2;int a1[10100],a2[10100],a3[10100]={0};char flag ='+';//保证始终都是位数长的减去小的//比如现在让你求10-200 我们可以算200-10 然后在结果前面加上负号//如果这个flag是正的则不需要输出if(s1.size()<s2.size()||(s1.size()==s2.size()&& s1<s2)){swap(s1,s2);flag='-';}//逆序存储for(int i=0;i<=s1.size();i++){a1[s1.size()-i-1]=s1[i]-'0';}for(int i=0;i<=s2.size();i++){a2[s2.size()-i-1]=s2[i]-'0';}for(int i=0;i<s1.size();i++){//先借好位if(a1[i]<a2[i])//需要借位的情况{a1[i]+=10;a1[i+1]--;}//再对应相减a3[i]=a1[i]-a2[i];}if(flag=='-'){cout<<flag;}int index=0;//找到倒序输出的起始位置for(int i=s1.size()-1;i>=0;i--){if(a3[i]!=0){index=i;break;}}for(int i=index;i>=0;i--){cout<<a3[i];}return 0;
}

问题


  1. 数组越界问题
  • 问题点

    for(int i=0;i<=s1.size();i++) {a1[s1.size()-i-1]=s1[i]-'0';
    }
    

    这里的循环条件是 i <= s1.size(),但字符串的索引范围是 [0, s1.size()-1],因此当 i == s1.size() 时会导致数组越界。

  • 修复方法:将循环条件改为 i < s1.size()


  1. 借位逻辑错误
  • 问题点

    if(a1[i] < a2[i]) {a1[i] += 10;a1[i+1]--;
    }
    

    如果 a1[i+1] 已经为 0,则再次借位会导致负值,从而产生错误结果。

  • 修复方法:在借位时确保高位有足够值可以借。可以通过递归借位的方式解决:

    if(a1[i] < a2[i]) {int j = i;while(j < s1.size() && a1[j+1] == 0) {a1[j+1] = 9; // 借位后恢复为9j++;}if(j < s1.size()) {a1[j+1]--;a1[i] += 10;}
    }
    

  1. 前导零问题
  • 问题点

    for(int i=s1.size()-1;i>=0;i--) {if(a3[i] != 0) {index = i;break;}
    }
    

    如果结果为 0(例如 1 - 1),则 index 会保持初始值 0,导致输出多余字符。

  • 修复方法:在输出前检查是否所有位均为 0,并直接输出 0

    bool all_zero = true;
    for(int i=0;i<s1.size();i++) {if(a3[i] != 0) {all_zero = false;break;}
    }
    if(all_zero) {cout << "0";return 0;
    }
    

  1. 符号处理问题
  • 问题点:如果两个数相等(例如 1 - 1),当前代码会输出 -0,这是不正确的。
  • 修复方法:在输出符号前检查结果是否为 0:
    if(flag == '-') {bool all_zero = true;for(int i=0;i<s1.size();i++) {if(a3[i] != 0) {all_zero = false;break;}}if(!all_zero) {cout << flag;}
    }
    

solution 2

#include <bits/stdc++.h>
using namespace std;int main() {string s1, s2;cin >> s1 >> s2;int a1[10100] = {0}, a2[10100] = {0}, a3[10100] = {0};char flag = '+';// 保证始终都是位数长的减去小的if(s1.size() < s2.size() || (s1.size() == s2.size() && s1 < s2)) {swap(s1, s2);flag = '-';}// 逆序存储for(int i = 0; i < s1.size(); i++) {a1[s1.size() - i - 1] = s1[i] - '0';}for(int i = 0; i < s2.size(); i++) {a2[s2.size() - i - 1] = s2[i] - '0';}// 高精度减法for(int i = 0; i < s1.size(); i++) {if(a1[i] < a2[i]) { // 需要借位的情况int j = i;while(j < s1.size() && a1[j+1] == 0) {a1[j+1] = 9; // 借位后恢复为9j++;}if(j < s1.size()) {a1[j+1]--;a1[i] += 10;}}a3[i] = a1[i] - a2[i];}// 检查是否所有位均为0bool all_zero = true;for(int i = 0; i < s1.size(); i++) {if(a3[i] != 0) {all_zero = false;break;}}if(all_zero) {cout << "0";return 0;}// 输出符号if(flag == '-') {bool has_non_zero = false;for(int i = 0; i < s1.size(); i++) {if(a3[i] != 0) {has_non_zero = true;break;}}if(has_non_zero) {cout << flag;}}// 找到倒序输出的起始位置int index = 0;for(int i = s1.size() - 1; i >= 0; i--) {if(a3[i] != 0) {index = i;break;}}// 输出结果for(int i = index; i >= 0; i--) {cout << a3[i];}return 0;
}
http://www.dtcms.com/wzjs/296736.html

相关文章:

  • 福州住房和建设局网站软文推广是什么意思?
  • 深圳最好的网站开发公司如何做网络营销
  • 网站如何自己做优化爱站网影院
  • 如何申请网站空间北京seo推广服务
  • app网站制作公司宁德市人力资源和社会保障局
  • 网站建设的培训seo优化个人博客
  • 网站 托管陕西seo公司
  • 内蒙古呼和浩特市做网站的公司aso搜索优化
  • 学校建设评建工作网站2024近期新闻
  • 大学哪个专业可以做网站泉州seo外包
  • 莆田企业免费建站seo百度seo排名优化软件
  • wordpress调用当前分类列表seo优化外链平台
  • 做门户网站找哪家公司口碑营销推广
  • 如何做网站的自由撰稿人seo是一种利用搜索引擎
  • 网站建设仟首先金手指13网络销售怎么样
  • 电脑无法登录建设银行网站公司网站模板
  • 泉州网站建设价格接外包网站
  • 苏州市建设职业中心网站天津网站优化公司
  • 动力无限西安网站建设互联网营销师培训大纲
  • 洛阳网站建设好做不百度seo标题优化软件
  • 做网站域名有什么用微指数查询入口
  • 响应式企业展示型网站模板网络营销策划的内容
  • 苏州企业商务网站建设谷歌浏览器下载手机版最新版
  • 公司网站搭建教程软件培训机构哪家好
  • 做同城特价的网站网站建设制作公司
  • 自己做网站卖东西需要交税吗最近有哪些新闻
  • 鹤壁网站开发seo整站优化系统
  • 建设云官网seo词条
  • 江西建设局网站百度地图在线查询
  • 美工做网站怎么收费整站外包优化公司