通用模板(vector版本)
1.加减
#include<bits/stdc++.h>
using namespace std;
vector<int >A, B;
bool cmp(vector<int >& A, vector<int >& B)//比较
{
if (A.size() != B.size())return A.size() > B.size();
else
{
for (int i = A.size() - 1; i >= 0; i--)
{
if (A[i] != B[i])return A[i] > B[i];
}
return true;
}
}
vector<int> add(vector<int >& A, vector<int >& B)//加法
{
vector<int>C;
int t = 0;
for (int i = 0; i < A.size() || i < B.size(); i++)
{
if (i < A.size())t += A[i];
if (i < B.size())t += B[i];
C.push_back(t % 10);
t /= 10;
}
if (t)C.push_back(1);
return C;
}
vector<int> sub(vector<int >& A, vector<int >& B)//减法,注意这里A是大于B的
{
vector<int>C;
int t = 0;
for (int i = 0; i < A.size(); i++)
{
t = A[i] - t;
if (i < B.size())t -= B[i];
C.push_back((t + 10) % 10);
if (t < 0)t = 1;
else t = 0;
}
while (C.size() > 1 && C.back() == 0)C.pop_back();
return C;
}
int main()
{
string a, b;
cin >> a >> b;
for (int i = a.size() - 1; i >= 0; i--)A.push_back(a[i] - '0');
for (int i = b.size() - 1; i >= 0; i--)B.push_back(b[i] - '0');
bool flag = 0;
if (!cmp(A,B))
{
flag = true;
swap(A, B);
}
auto add_ans = add(A, B);
for (int i = add_ans.size() - 1; i >= 0; i--)
{
cout << add_ans[i];
}
cout << endl;
auto sub_ans = sub(A, B);
for (int i = sub_ans.size() - 1; i >= 0; i--)
{
if (flag && i == sub_ans.size() - 1)cout << '-';
cout << sub_ans[i];
}
cout << endl;
return 0;
}
2.乘除
#include<bits/stdc++.h>
using namespace std;
vector<int>mul(vector<int>& A, int b)//乘法
{
vector<int >C;
int t = 0;
for (int i = 0; i < A.size() || t; i++)
{
if (i < A.size())
{
t += A[i] * b;
}
C.push_back(t % 10);
t /= 10;
}
return C;
}
vector<int>div(vector<int>& A, int &b,int &t)//除法
{
vector<int>C;
t = 0;
for (int i = A.size() - 1; i >= 0; i--)
{
t = t * 10 + A[i];
C.push_back(t /b);
t%=b;
}
reverse(C.begin(), C.end());//为和加减乘除保持一致
while (C.size() > 1 && C.back() == 0)C.pop_back();
return C;
}
int main()
{
int b;
string a;
vector<int>A;
cin >> a >> b;
for (int i = a.size() - 1; i >= 0; i--)A.push_back(a[i]- '0');
auto mul_ans = mul(A, b);
for (int i = mul_ans.size()-1; i >= 0; i--)
{
cout << mul_ans[i];
}
int t;//代表余数
auto div_ans = div(A, b,t);
for (int i = div_ans.size() - 1; i >= 0; i--)
{
cout << div_ans[i];
}
cout << endl << t << endl;
}
高精度
首先引入一篇较好的文章来了解什么是高精度,以及高精度基本的运算(加减乘除)。
https://blog.csdn.net/fanyun_01/article/details/79967170
以及一道简单的入门题目
以及本人代码
#include<bits/stdc++.h>
using namespace std;
int a[10000], b[10000], ans[10000];
int main() {
string A, B;
cin >> A >> B;
int len_A, len_B;
len_A = A.length();
len_B= B.length();//位数储存
for (int i = 1; i <=len_A; i++) {
a[i] = A[len_A - i] - '0';//注意A是由A[0]开始的
}
for (int i = 1; i <=len_B; i++) {
b[i] = B[len_B - i] - '0';
}//现在a,b已经变为倒序,为方便后续的进位
int len =(len_A>len_B?len_A:len_B);//确定最长位数
for (int i = 1; i <= len; i++) {
ans[i] += a[i] + b[i];//注意是+=而不是=,因为一开是有可能因为有进位的而有初值
ans[i + 1] += (ans[i] / 10);//进位
ans[i] %= 10;//保留个位
}
len++;
if((ans[len] == 0) && (len > 1))len--;//如果有0,去掉最高位的0,如果是其他值,则保留
for (int i = len; i >= 1; i--) {
cout << ans[i];
}
return 0;
}
以及一道高精度加低精度,高精度乘以高精度以及高精度除以低精度的综合运用
AC代码(运用高斯公式简化计算)
#include<iostream>
#include<string.h>
using namespace std;
#define max 202
int a[max], b[max], c[max];
int main()
{
string s;
cin >> s;
int x, i, j;
int len = s.size();
for (int i = 0; i < len; i++) {
a[len - i] = s[i] - '0';
b[len - i] = s[i] - '0';
}//注意这个是len-i,则最小一项为1
b[1]++;//首项加末相
for (int i = 1; i <= len; i++) {
if (b[i] == 10) {
b[i] = 0;
b[i + 1]++;
}//进位
else break;
}
int len_B = len + 1;
while (b[len_B] == 0 && len_B > 1)len_B--;//防止出现999之类的数据
//高精度乘法
for (int i = 1; i <= len_B; i++) {
x = 0;
for (int j = 1; j <= len; j++) {
c[i + j - 1] += a[j] * b[i] + x;//建议写一个比较小的俩位数相乘来方便理解,x用来表示进位
x = c[i + j - 1] / 10;
c[i + j - 1] %= 10;
}//注意最后赋值的是i+len-1,i+len(j=len时候)没有得到进位数值,则下面补充
c[i + len] = x;
}//c此时是正序
int lenc = len+len_B+1;
while (c[lenc] == 0 && lenc > 1)lenc--;
for (int i = lenc; i >= 1; i--) {
if (c[i] % 2 == 0) {
c[i] /= 2;
}
else {
c[i - 1] += 10;
c[i] /= 2;
}
}
while (c[lenc] == 0 && lenc > 1) lenc--;//去除前面的0
for (int i = lenc; i >= 1; i--) {
cout << c[i];
}
}
以及一个刚开始写的超时代码
#include<bits/stdc++.h>
using namespace std;
int a[10005];//1表示个位,2表示十位依次类推
int main() {
int n; cin >> n;
int len=1, temp;//len表示目前的位数,temp用于进位
a[1] = 1;//对初始对象赋值
for (int i = 2; i <= n; i++) {
temp = 0;//重置
for (int j = 1; j <= len; j++) {
if (j == 1) {
a[j] += i + temp;
temp = a[j] / 10;
a[j] %= 10;
}//一开始对个位的操作
else {
a[j] += temp;//后面位数改变靠前面一位进位实现
temp = a[j] / 10;
a[j] %= 10;
}
}
if (temp != 0)a[++len] = temp;//表示进过位,说明总位数len发生了改变
}
for (int i = len; i >= 1; i--)cout << a[i];//倒叙输出
cout << endl;
return 0;
}//时间复杂度太高,超时!
以及一个补充题目有兴趣的可以去洛谷写写(这道题主要是对于未知位数的处理,思想很独到值得一些)
以及本人代码
#include<bits/stdc++.h>
using namespace std;
int a[150], ans[150];
int main() {
int n,count=100;
cin >> n;
a[1] = ans[1] = 1;//a用来储存n-1的阶乘
for (int i = 2; i <= n; i++) {
for (int j = 1; j <= 100; j++) {//最多不超过100位,当然也可以再定大一些
//不过尽量看看代码规定时长不要超时
a[j] *= i;//作乘法,给每一项相乘
}
for (int j = 1; j <= 100; j++) {
if (a[j] > 9) {
a[j + 1] += a[j] / 10;//进位
a[j] %= 10;
}
}
for (int j = 1; j <= 100; j++) {
ans[j] += a[j];
for (int j = 1; j <= 100; j++) {
if (ans[j] > 9) {
ans[j + 1] += ans[j] / 10;//进位
ans[j] %= 10;
}
}
}
}
while (ans[count] == 0)count--;//对多余位数进行消去
for (int i = count; i >= 1; i--) {
cout << ans[i];
}
return 0;
}
模拟
一道简单题来引入(https://www.luogu.com.cn/problem/P1042)
本人代码
#include<bits/stdc++.h>
using namespace std;
char ans[100];
int main()
{
char a;
int W=0, L=0;
int count = 0;
while ((a=getchar()))
{
if (a == 'E') {
cout << W << ":" << L << endl;
break;
}
if (a == '/n')continue;//防止空格被记录
ans[++count] = a;//从1开始计数,并且不会记录E
if (a == 'W')W++;
else if (a == 'L')L++;//abs() fabs()分别可以对整型和浮点型求绝对值
if (W >= 11 && W - L >= 2||L>=11&&L-W>=2) {
cout << W << ":" << L << endl;
W = 0, L = 0;
}
}
W = 0, L = 0;//归零
cout << endl;
for (int i = 1; i <= count; i++) {
if (ans[i] == 'W')W++;
else if (ans[i] == 'L')L++;
if (W >= 21 && W - L >= 2 || L >= 21 && L - W >= 2) {
cout << W << ":" << L << endl;
W = 0, L = 0;
}
}
if (W != 0 || L != 0)cout << W << ":" << L << endl;
return 0;
}
其中比较值得借鉴的是对于空格细节的处理,以及对有特定终止符号的字符串如何读取和储存。