4 条题解
-
3
C++高精度函数写法
#include <iostream> #define N 10010 using namespace std; string a, b; //以下三个函数高精除法(取余)要用到 int compare(int x[], int y[]){ //比较两个高精数据(数组)大小,x大于y返回1,小于返回-1,等于返回0 if(x[0] != y[0]) return x[0] > y[0] ? 1 : -1; for(int i = x[0]; i; i--){ if(x[i] > y[i]) return 1; if(x[i] < y[i]) return -1; } return 0; } void copy(int x[], int y[], int step){ //将y右移step位赋值给x,即 x = y * 10 ^ step for(int i = 1; i <= y[0]; i++) x[i + step] = y[i]; x[0] = y[0] + step; } void sub(int x[], int y[]){ //模拟减法竖式运算 for(int i = 1; i <= x[0]; i++){ if(x[i] < y[i]){ x[i + 1]--; x[i] += 10; } x[i] -= y[i]; } while(!x[x[0]] && x[0]) x[0]--; } string _add(string x, string y){ //高精度加法 string res; int nx[N] = {0}, ny[N] = {0}, ans[N + 1] = {0}; nx[0] = x.size(), ny[0] = y.size(), ans[0] = max(nx[0], ny[0]) + 1; //数组第0位存储长度 for(int i = nx[0]; i; i--) nx[i] = x[nx[0] - i] - '0'; //逆序存储 for(int i = ny[0]; i; i--) ny[i] = y[ny[0] - i] - '0'; for(int i = 1; i <= ans[0]; i++){ //模拟加法竖式运算 ans[i + 1] += (ans[i] + nx[i] + ny[i]) / 10; ans[i] = (ans[i] + nx[i] + ny[i]) % 10; } while(!ans[ans[0]] && ans[0]) ans[0]--; //去除前导0 if(!ans[0]) return "0"; //如果长度为0直接返回0 for(int i = ans[0]; i; i--) res += ans[i] + '0'; //逆序回来并返回 return res; } string _minus(string x, string y){ //高精度减法 if(x.size() < y.size() || x.size() == y.size() && x < y) return "-" + _minus(y, x); //如果 x < y 返回 - (y - x) string res; int nx[N] = {0}, ny[N] = {0}; nx[0] = x.size(), ny[0] = y.size(); for(int i = nx[0]; i; i--) nx[i] = x[nx[0] - i] - '0'; for(int i = ny[0]; i; i--) ny[i] = y[ny[0] - i] - '0'; for(int i = 1; i <= nx[0]; i++){ //模拟减法竖式运算(可用上面sub函数代替) if(nx[i] < ny[i]){ nx[i + 1]--; nx[i] += 10; } nx[i] -= ny[i]; } while(!nx[nx[0]] && nx[0]) nx[0]--; if(!nx[0]) return "0"; for(int i = nx[0]; i; i--) res += nx[i] + '0'; return res; } string _mult(string x, string y){ //高精度乘法 string res; int nx[N] = {0}, ny[N] = {0}, ans[N << 1] = {0}; nx[0] = x.size(), ny[0] = y.size(), ans[0] = nx[0] + ny[0]; for(int i = nx[0]; i; i--) nx[i] = x[nx[0] - i] - '0'; for(int i = ny[0]; i; i--) ny[i] = y[ny[0] - i] - '0'; for(int i = 1; i <= nx[0]; i++){ //模拟乘法竖式运算 for(int j = 1; j <= ny[0]; j++){ ans[i + j] += (ans[i + j - 1] + nx[i] * ny[j]) / 10; ans[i + j - 1] = (ans[i + j - 1] + nx[i] * ny[j]) % 10; } } while(!ans[ans[0]] && ans[0]) ans[0]--; if(!ans[0]) return "0"; for(int i = ans[0]; i; i--) res += ans[i] + '0'; return res; } string _div(string x, string y){ //高精度除法 if(x.size() < y.size() || x.size() == y.size() && x < y) return "0"; //如果 x < y 返回 0 string res; int nx[N] = {0}, ny[N] = {0}, ans[N] = {0}; nx[0] = x.size(), ny[0] = y.size(), ans[0] = nx[0] - ny[0] + 1; for(int i = nx[0]; i; i--) nx[i] = x[nx[0] - i] - '0'; for(int i = ny[0]; i; i--) ny[i] = y[ny[0] - i] - '0'; for(int i = ans[0]; i; i--){ //模拟除法竖式运算 int temp[N] = {0}; copy(temp, ny, i - 1); while(compare(nx, temp) >= 0){ sub(nx, temp); ans[i]++; } } while(!ans[ans[0]] && ans[0]) ans[0]--; for(int i = ans[0]; i; i--) res += ans[i] + '0'; return res; } string _mod(string x, string y){ //高精度取余 if(x.size() < y.size() || x.size() == y.size() && x < y) return x; //如果 x < y 返回 x string res; int nx[N] = {0}, ny[N] = {0}; nx[0] = x.size(), ny[0] = y.size(); for(int i = nx[0]; i; i--) nx[i] = x[nx[0] - i] - '0'; for(int i = ny[0]; i; i--) ny[i] = y[ny[0] - i] - '0'; for(int i = nx[0] - ny[0] + 1; i; i--){ //模拟除法竖式运算 int temp[N] = {0}; copy(temp, ny, i - 1); while(compare(nx, temp) >= 0){ sub(nx, temp); } } if(!nx[0]) return "0"; for(int i = nx[0]; i; i--) res += nx[i] + '0'; return res; } int main() { ios::sync_with_stdio(false); cin.tie(0); cout.tie(0); cin >> a >> b; cout << _add(a, b) << endl; cout << _minus(a, b) << endl; cout << _mult(a, b) << endl; cout << _div(a, b) << endl; cout << _mod(a, b) << endl; return 0; }
不过这道题为十六进制,所以需稍加改动
#include <iostream> #define N 10010 using namespace std; string a, b; string _add(string x, string y){ string res; int nx[N] = {0}, ny[N] = {0}, ans[N + 1] = {0}; nx[0] = x.size(), ny[0] = y.size(), ans[0] = max(nx[0], ny[0]) + 1; for(int i = nx[0]; i; i--){ if(isdigit(x[nx[0] - i])) nx[i] = x[nx[0] - i] - '0'; else nx[i] = x[nx[0] - i] - 'A' + 10; } for(int i = ny[0]; i; i--){ if(isdigit(y[ny[0] - i])) ny[i] = y[ny[0] - i] - '0'; else ny[i] = y[ny[0] - i] - 'A' + 10; } for(int i = 1; i <= ans[0]; i++){ ans[i + 1] += (ans[i] + nx[i] + ny[i]) / 16; ans[i] = (ans[i] + nx[i] + ny[i]) % 16; } while(!ans[ans[0]] && ans[0]) ans[0]--; if(!ans[0]) return "0"; for(int i = ans[0]; i; i--){ if(ans[i] >= 0 && ans[i] <= 9) res += ans[i] + '0'; else res += ans[i] + 'A' - 10; } return res; } int main() { ios::sync_with_stdio(false); cin.tie(0); cout.tie(0); cin >> a >> b; cout << _add(a, b) << endl; return 0; }
-
-1
/*#include <iostream> using namespace std; const int Maxn=10; int a[Maxn],b[Maxn],c[2*Maxn]; int lena, lenb, lenc, t; int main() { string s1,s2; cin>>s1>>s2; //s1,s2为十进制字符串值,如:s1=(190)D, s2=(80)D lena=s1.length()-1; lenb=s2.length()-1; //lena: 数据a的最高权位,对应数值a实际存储下标:[0..lena] lenc=lena+lenb+1; //lenc: 相乘后的结果c[]位数是: lena+lenb+1, 也可能是: lena+lenb for(int i=0; i<=lena; i++){ //1. 将s1字符串转存入数组a[]中, 考虑到高位可以拓展, 因此最低位放在0位置 if('0'<=s1[i] and s1[i]<='9') t=s1[i]-48; else t=s1[i]-'A'+10; a[lena-i]=t; } for(int i=0; i<=lenb; i++){ if('0'<=s2[i] and s2[i]<='9') t=s2[i]-48; else t=s2[i]-'A'+10; b[lenb-i]=t; } for(int i=0; i<=lena; i++){ //2. 数据a与数据b按对应位置相乘, 权位i与权位j相乘, 其结果累加到数组c[i+j](权位:i+j)中 for(int j=0; j<=lenb; j++){ c[i+j]=c[i+j]+a[i]*b[j]; } } for(int i=0; i<=lenc; i++){ //3. 将相乘后的结果进行整理,整理成10进制 c[i+1]+=c[i]/10; c[i]%=10; } while(c[lenc]==0 && lenc>0) lenc--; // 最高位lenc值可能存在多个0, 将高位无效的0进行消除,(但要确保至少留下1位, 比如:乘以0) for(int i=lenc; i>=0; i--){ //4. 从高位到低位, 依次输出高精度数据c[lenc..0] printf("%d",c[i]); } return 0; }*/ //高精度乘法; /*#include <iostream> using namespace std; const int Maxn=10; int a[Maxn],b[Maxn],c[Maxn]; int lena, lenb, lenc, t; int main() { string s1,s2; cin>>s1>>s2; //s1,s2为十六进制字符串值,如:s1=(B90)H, s2=(80)H if(s1.length()<s2.length() or(s1.length()==s2.length() && s1<s2)){ //若s1数据小于s2数据, 则输出"-", 同时进行交换,s1与s2比较最高位字母或数字先后顺序,比较大小; cout<<"-"; swap(s1,s2); } lena=s1.length()-1; lenb=s2.length()-1; //lena: 数据a的最高权位,对应数值a实际存储下标:[0..lena] lenc=lena; //lenc: 数据a大于数据b, a-b, 结果c最大可能权位<=lena for(int i=0; i<=lena; i++){ //1. 将s1字符串转存入数组a[]中, 考虑到高位可以拓展, 因此最低位放在0位置 if('0'<=s1[i] and s1[i]<='9') t=s1[i]-48; else t=s1[i]-'A'+10; a[lena-i]=t; } for(int i=0; i<=lenb; i++){ if('0'<=s2[i] and s2[i]<='9') t=s2[i]-48; else t=s2[i]-'A'+10; b[lenb-i]=t; } for(int i=0; i<=lenc; i++){ //2. 将数据a与数据b按对应位置相减 c[i]=a[i]-b[i]; } for(int i=0; i<=lenc; i++){ //3. 将各个位置数据, 从低位到高位, 依次整理成16进制数值(0..15) if(c[i]<0){c[i]+=16; c[i+1]--;} // 整理负数 } while(c[lenc]==0 && lenc>0) lenc--; // 最高位lenc值可能存储多个0, 将高位无效的0进行消除,(但要确保至少留下1位) for(int i=lenc; i>=0; i--){ //4. 从高位到低位, 依次输出高精度数据c[lenc..0] if(c[i]>=10){printf("%c",c[i]+55);} else{printf("%d",c[i]);} } return 0; }*/ //高精度减法; #include <iostream> using namespace std; const int Maxn=100; int a[Maxn],b[Maxn],c[Maxn]; int lena, lenb, lenc, t; int main() { string s1,s2; cin>>s1>>s2; //s1,s2为十六进制字符串值,如:s1=(B90)H, s2=(80)H lena=s1.length()-1; lenb=s2.length()-1; //lena: 数据a的最高权位,对应数值a实际存储下标:[0..lena] lenc=max(lena, lenb)+1; //lenc: 数据a+b, 产生结果c的最大可能权位,实际也可能是lenc-1 for(int i=0; i<=lena; i++){ //1. 将s1字符串转存入数组a[]中, 考虑到高位可以拓展, 因此最低位放在0位置 if('0'<=s1[i] and s1[i]<='9') t=s1[i]-48; else t=s1[i]-'A'+10; a[lena-i]=t; } for(int i=0; i<=lenb; i++){ if('0'<=s2[i] and s2[i]<='9') t=s2[i]-48; else t=s2[i]-'A'+10; b[lenb-i]=t; } for(int i=0; i<=lenc; i++){ //2. 将数据a与数据b按对应位置相加 c[i]=a[i]+b[i]; } for(int i=0; i<=lenc; i++){ //3. 将各个位置数据, 从低位到高位, 依次整理成16进制数值(0..15) c[i+1]+=c[i]/16; c[i]%=16; } if(c[lenc]==0) lenc--; // 最高位lenc值为0, 则不存在,进行退位 for(int i=lenc; i>=0; i--){ //4. 从高位到低位, 依次输出高精度数据c[lenc..0] if(c[i]>=10){printf("%c",c[i]+55);} else{printf("%d",c[i]);} } return 0; }
-
-1
#include <iostream> using namespace std; const int Maxn=100; int a[Maxn],b[Maxn],c[Maxn]; int lena, lenb, lenc, t; int main() { string s1,s2; cin>>s1>>s2; //s1,s2为十六进制字符串值,如:s1=(B90)H, s2=(80)H lena=s1.length()-1; lenb=s2.length()-1; //lena: 数据a的最高权位,对应数值a实际存储下标:[0..lena] lenc=max(lena, lenb)+1; //lenc: 数据a+b, 产生结果c的最大可能权位,实际也可能是lenc-1 for(int i=0; i<=lena; i++){ //1. 将s1字符串转存入数组a[]中, 考虑到高位可以拓展, 因此最低位放在0位置 if('0'<=s1[i] and s1[i]<='9') t=s1[i]-48; else t=s1[i]-'A'+10; a[lena-i]=t; } for(int i=0; i<=lenb; i++){ if('0'<=s2[i] and s2[i]<='9') t=s2[i]-48; else t=s2[i]-'A'+10; b[lenb-i]=t; } for(int i=0; i<=lenc; i++){ //2. 将数据a与数据b按对应位置相加 c[i]=a[i]+b[i]; } for(int i=0; i<=lenc; i++){ //3. 将各个位置数据, 从低位到高位, 依次整理成16进制数值(0..15) c[i+1]+=c[i]/16; c[i]%=16; } if(c[lenc]==0) lenc--; // 最高位lenc值为0, 则不存在,进行退位 for(int i=lenc; i>=0; i--){ //4. 从高位到低位, 依次输出高精度数据c[lenc..0] if(c[i]>=10){printf("%c",c[i]+55);} else{printf("%d",c[i]);} } return 0; }
- 1
信息
- ID
- 98
- 时间
- 1000ms
- 内存
- 128MiB
- 难度
- 7
- 标签
- 递交数
- 354
- 已通过
- 84
- 上传者