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

【算法笔记】模拟与高精度加减乘除

前言:模拟一般主要考察我们的代码能力,同时多做模拟题还可以提升我们的代码能力,主要考察的是你的代码实现能力,而高精度加减乘除则是一个模板,用于处理多位数运算的问题

1.模拟

1.1多项式输出

代码示范:

#include <iostream> #include <cmath> using namespace std; int main() { int n; cin >> n; for (int i = n; i >= 0; i--) { int x; cin >> x; if (x == 0) continue; if (x < 0) cout << '-'; else { if (i != n) cout << "+"; } //处理数字 x = abs(x); if (x != 1 || (x == 1 && i == 0)) { cout << x; } //处理次数 if (i == 1) cout << "x"; else if(i == 0) continue; else cout << "x^" << i; } }

我们可以将这个问题拆解为三个方面: (1) : 处理符号 (2) : 处理数字 (3) : 处理次数

先来看符号问题,符号为 - 号则正常输出,当项目不为第一项则正常输出 + 号

因为我们已经处理过了符号的问题所以我们可以先对这个数字取个绝对值,这里主要需要处理的是数字为0和1的特殊情况,当数字不为1或者数字为1并且是最后一项则正常输出

接下来处理次数的问题,在当次数为1的时候我们不会输出次数,当为0时则不输出,后面的正常情况我们正常输出即可,但是需要注意格式的问题容易掉坑


1.2蛇形方阵

这道题不难理解,主要是处理转向的问题非常麻烦,所以这里介绍一个改变方向的技巧,这个技巧后面还会用到很多,尤其是在dfs和bfs中就很容易遇到这种场景:

这个蛇的转向主要为上、下、左、右,所以我们可以创建X、Y两个方向的偏移量数组, 设坐标为:

那蛇依次向右、下、左、上移动的坐标偏移量为:

所以可以定义数组为:

int dx[4] = {0, 1, 0, -1}; int dy[4] = {1, 0, -1, 0};

我们可以先计算出下一步的蛇的坐标,用这些数组来改变蛇的方向,落实在代码上就是:

#include <iostream> using namespace std; const int N = 15; int dx[4] = {0, 1, 0, -1}; int dy[4] = {1, 0, -1, 0}; int he[N][N]; int n; int main() { cin >> n; int pos = 0; int x = 1, y = 1; int cnt = 1; while (cnt <= n*n) { he[x][y] = cnt++; int a = x + dx[pos], b = y + dy[pos]; if (a < 1 || a > n || b < 1 || b > n || he[a][b])//防止越界和重复 { pos = (pos + 1) % 4; a = x + dx[pos]; b = y + dy[pos]; } x = a; y = b; } for (int i = 1; i <= n; i++) { for (int j = 1; j <= n; j++) { printf("%3d", he[i][j]); } printf("\n"); } return 0; }

其中模4可以让蛇往固定四个方向走


1.3字符串的展开

这道题非常考验细节,也是让我坐牢的好久,和第一题一样分类讨论一下就好了:

#include <iostream> #include <algorithm> using namespace std; int p1, p2, p3; string s; string ret; int n; bool isdig(char ch) { return ch >= '0' && ch <= '9'; } bool islet(char ch) { return ch >= 'a' && ch <= 'z'; } void add(char left, char right) { char ch = ++left; string sz; //处理p2的情况 for (char i = ch; i < right; i++) { char tem = i; if (p1 == 2 && islet(tem)) tem -= 32; if (p1 == 3) tem = '*'; for (int j = 0; j < p2; j++) { sz += tem; } } if (p3 == 2) reverse(sz.begin(), sz.end()); ret += sz; } int main() { cin >> p1 >> p2 >> p3 >> s; n = s.size(); for (int i = 0; i < n; i++) { char ch = s[i]; if (ch != '-' || i == 0 || i == n - 1) ret += ch; else { char left = s[i - 1], right = s[i + 1]; if (left < right && (isdig(left) && isdig(right)) || (islet(left) && islet(right) && left < right)) { add(left, right); } else ret += ch; } } cout << ret << endl; return 0; }

2.高精度加减乘除

2.1高精度加法

当语言内置的类型无法满足多位运算的需求时就需要使用高精度加减乘除这个模板,主要是把我们小学阶段学的加减乘除模拟一下就可以了。

这里我们是用数组来完成每一位的模拟计算,我们先用字符串来读入数字,但是我们需要把里面的字符(数字)逆序存到数组,比如读入12345,在存入数组就要54321的存,这是因为我们是要用低位开始模拟计算的

#include <iostream> using namespace std; const int N = 1e6 + 10; int a[N], b[N], c[N]; int la, lb, lc; string s1, s2; void add(int a[], int b[], int c[]) { for (int i = 0; i < lc; i++) { c[i] += a[i] + b[i]; c[i + 1] = c[i] / 10;//处理进位 c[i] %= 10; } if (c[lc]) lc++;//处理首位 } int main() { cin >> s1 >> s2; la = s1.size(); lb = s2.size(); lc = max(la, lb); for (int i = 0; i < la; i++) a[la - 1 - i] = s1[i] - '0';//转陈数字,逆序着存 for (int i = 0; i < lb; i++) b[lb - 1 - i] = s2[i] - '0'; add(a, b, c); for (int i = lc - 1; i >= 0; i--) { cout << c[i]; } return 0; }

2.2高精度减法

减法同样是模拟先,和加法差不多,只不过从需要进位变成了借位,别忘了处理一个前面的零就可以了

先判断一下结果的正负,让绝对值大的减去绝对值小的方便我们模拟:

#include <iostream> using namespace std; const int N = 1e6 + 10; int a[N], b[N], c[N]; int la, lb, lc; string s1, s2; bool cmp(string& s1, string& s2) { if (s1.size() != s2.size()) return s1.size() < s2.size(); return s1 < s2; } void sub(int a[], int b[], int c[]) { for (int i = 0; i < lc; i++) { c[i] += a[i] - b[i]; if (c[i] < 0)//处理借位的情况 { c[i + 1] -= 1; c[i] += 10; } } while (lc > 1 && c[lc - 1] == 0) lc--;//处理前导零 } int main() { cin >> s1 >> s2; if (cmp(s1, s2)) { swap(s1, s2); cout << '-'; } la = s1.size(); lb = s2.size(); lc = max(la, lb); for (int i = 0; i < la; i++) a[la - 1 - i] = s1[i] - '0'; for (int i = 0; i < lb; i++) b[lb - 1 - i] = s2[i] - '0'; sub(a, b, c); for (int i = lc - 1; i >= 0; i--) cout << c[i]; return 0; }

2.3高精度乘法

乘法的进位相比与加法麻烦一点,但我发现了一个规律,假如紫色对应着下标的话,那结果的小标应该为两个乘除的下标相加,所以我们可以先把结果存入数组c中,让后通过一层循环像加法那样处理掉所有的进位:

紫色对应着这个数字的下标

最后处理所有的前导零即可:

#include <iostream> using namespace std; const int N = 1e6 + 10; int a[N], b[N], c[N]; int la, lb, lc; string s1, s2; void mul(int a[], int b[], int c[]) { for (int i = 0; i < la; i++) { for (int j = 0; j < lb; j++) { c[i + j] += a[i] * b[j]; } } //处理进位 for (int i = 0; i < lc; i++) { c[i + 1] += c[i] / 10; c[i] %= 10; } while (lc > 1 && c[lc - 1] == 0) lc--;//处理前导零 } int main() { cin >> s1 >> s2; la = s1.size(); lb = s2.size(); lc = la + lb; for (int i = 0; i < la; i++) a[la - 1 - i] = s1[i] - '0'; for (int i = 0; i < lb; i++) b[lb - 1 - i] = s2[i] - '0'; mul(a, b, c); for (int i = lc - 1; i >= 0; i--) cout << c[i]; return 0; }

2.4高精度除法

除法也是比较简单的模拟,但是我们这次从高位向低位处理,因为我们平常就是这么算的吧哈哈

然后余数对下一位来说要乘10就完了:

#include <iostream> using namespace std; const int N = 1e6 + 10; int a[N], b, c[N]; int la, lc; void sub(int a[], int b, int c[]) { long long t = 0; for (int i = la - 1; i >= 0; i--) { t = t * 10 + a[i]; c[i] = t / b; t %= b; } while (lc > 1 && c[lc - 1] == 0) lc--; } int main() { string s; cin >> s >> b; la = s.size(); lc = la; for (int i = 0; i < la; i++) a[la - 1 - i] = s[i] - '0'; sub(a, b, c); for (int i = lc - 1; i >= 0; i--) cout << c[i]; return 0; }

http://www.jsqmd.com/news/663392/

相关文章:

  • 资本流向正在静默转向AGI基建,2026年前窗口期仅剩8.3个月——SITS2026闭门数据首度公开
  • 别再搞混了!用大白话图解PostgreSQL的实例、数据库和Schema(附真实项目踩坑经验)
  • 动网格实战:Spring光顺法原理详解与案例剖析
  • Godot 2D碰撞体实战:从FlappyBird看RigidBody2D与StaticBody2D的碰撞艺术
  • 别急着点‘不报告’!深入解读AD编译警告‘off grid pin’的栅格设置与PCB布线隐患
  • InfoComm China 2026 开幕,TCL 携智慧显示方案参展,多领域展示创新实力
  • 测试库与生产库怎么应对同步中断断点续传_无损发布与更新方案
  • 2026年降AI率工具排行榜怎么选?3招避开智商税
  • 微动弹性带方法实战:从能量地形到过渡态精准定位
  • AI编程革命:Codex如何高效生成自动化脚本
  • 从化学到计算机:如何根据你的专业,精准选择最对口的学术文献数据库?
  • 【2026年最新600套毕设项目分享】外卖微信小程序的研究与开发(30099)
  • 高性能本地推理解决方案:llama-cpp-python实现大语言模型部署与优化
  • DIYGW UniApp可视化工具深度评测:对比传统编码开发到底能省多少时间?
  • CSS Grid布局如何解决图片溢出网格单元_设置object-fit与网格尺寸.txt
  • HPH精密构造全解析
  • 【2026年最新600套毕设项目分享】宠物微信小程序(30100)
  • AGI规模化训练崩塌预警,SITS2026提出5层冗余验证机制——从芯片级到语义层的全栈防御体系
  • 2.1 第一个C语言程序
  • 第九篇技术笔记:PoDL:一根线,供电上网两不误
  • 告别网络‘假死’!用STM32CubeMX配置LWIP的TCP保活(KeepAlive)与链路状态回调
  • 从Logo到生态:解码全球主流IC公司的品牌标识与战略定位
  • 从图像处理到雷达感知:搞懂‘多维傅里叶变换’,这一篇就够了(附Matlab/Octave实例)
  • 软件建造者管理化的复杂对象构建
  • 抓住鸿蒙流量红利!2026华为应用商店ASO优化全解
  • Akagi雀魂AI辅助工具:你的个人麻将教练,实时分析提升技术
  • 20252808 2025-2026-2 《网络攻防实践》第五次作业
  • 性能提升的真相|WebGPU 到底能让 Highcharts 快多少?
  • Java高频面试场景题07
  • Postman 在线测试:简单易懂