高精度运算
之前整过这个问题,但是只晓得这是大整数运算,因为最早接触这个是学java的时候,有个BigInteger
,现在才晓得这叫高精度运算。
高精度运算详解
这篇文章讲的真的好,很详细易懂,之前感觉很复杂的过程,一哈就简单多了。
记录一哈自己的模板,但是都是从这篇文章中学的,之前都是直接通过string
就整了,感觉效率太低,而且写的有点复杂,特别是乘法,除法之前都不会。
有些时候题目会给前导零,处理输入的时候要预防一哈
void getin(int *shuzu){
memset(input, 0, sizeof(input));
memset(shuzu, 0, sizeof(shuzu));
scanf("%s", input);
int n = strlen(input);
for(int i = 0; i < n; i ++)
shuzu[n-i] = input[i] - '0';
int i = n;
while(shuzu[i] == 0 && i > 1) i -- ;
shuzu[0] = i;
}
加法
模板题:vodevs3116
#include<iostream>
#include<cstdio>
#include<cstring>
using namespace std;
#define maxn 10000
char st[10000];
void print(int *shuzu){
for(int i = shuzu[0]; i >= 1; i --) cout << shuzu[i]; cout << endl;
}
void inputNum(int *shuzu){
memset(st, 0, sizeof(st));
scanf("%s", st);
int length = strlen(st);
for(int i = 0; i < length; i ++){
shuzu[length - i] = st[i] - '0';
}
shuzu[0] = length;
}
void add(int *a, int *b, int *c){
int i, jin = 0;
for(i = 1; i<=a[0] || i<=b[0]; i ++){
c[i] = a[i] + b[i] + jin;
jin = c[i] / 10;
c[i] %= 10;
}
if(jin > 0) c[i++] = jin;
c[0] = i - 1;
}
int main(){
int a[maxn], b[maxn], c[maxn];
inputNum(a); inputNum(b);
add(a, b, c);
for(int i = c[0]; i >= 1; i --) cout << c[i] ; cout << endl;
return 0;
}
减法
模板题:codevs3115
#include<iostream>
#include<cstdio>
#include<cstring>
using namespace std;
#define maxn 10000
char st[maxn];
void print(int *shuzu){
for(int i = shuzu[0]; i >= 1; i --) cout << shuzu[i]; cout << endl;
}
void inputNum(int *shuzu){
memset(st, 0, sizeof(st));
memset(shuzu, 0, sizeof(int)*1000);
scanf("%s", st);
int length = strlen(st);
for(int i = 0; i < length; i ++) shuzu[length - i] = st[i] - '0';
shuzu[0] = length;
}
bool compare(int *a, int *b){
if(a[0] > b[0]) return true;
if(a[0] < b[0]) return false;
for(int i = 1; i <= a[0]; i ++) {
if(a[i] > b[i]) return true;
if(a[i] < b[i]) return false;
}
}
void sub(int *a, int *b, int *c){
for(int i = 0; i <= a[0]; i ++) c[i] = a[i];
int i;
for( i = 1; i <= c[0]; i ++) {
if(c[i] < b[i]) {
c[i + 1] --;
c[i] += 10;
}
c[i] -= b[i];
}
while(c[i] == 0) i --;
c[0] = i;
}
int main(){
int a[maxn], b[maxn], c[maxn];
inputNum(a); inputNum(b);
if(compare(a, b)) sub(a, b, c);
else {
sub(b, a, c);
cout << "-" ;
}
print(c);
return 0;
}
乘法
模板题 :codevs3117
#include<iostream>
#include<cstring>
#include<cstdio>
using namespace std;
#define maxn 100000
char st[maxn];
void print(int *shuzu){
for(int i = shuzu[0]; i >= 1; i --) cout << shuzu[i]; cout << endl;
}
void inputNum(int *shuzu){
memset(shuzu, 0, sizeof(int)*1000);
memset(st, 0, sizeof(st));
scanf("%s", st);
int length = strlen(st);
for(int i = 0; i < length; i++) shuzu[length - i] = st[i] - '0';
shuzu[0] = length;
}
void mul(int *a, int *b, int *c){
memset(c, 0, sizeof(int)*300000);
for(int i = 1; i <= b[0]; i ++){
int jin = 0, j;
for(j = 1; j <= a[0]; j ++){
c[i+j-1] += a[j]*b[i] + jin;
jin = c[i+j-1] / 10;
c[i+j-1] %= 10;
}
if(jin > 0) c[i+j-1] = jin;
}
int i = a[0] + b[0];
while(c[i] == 0 && i > 1) i --;
c[0] = i;
print(c);
}
int main(){
int a[maxn], b[maxn], c[300000];
inputNum(a); inputNum(b);
mul(a, b, c);
return 0;
}
HDU1041
这是递推+高精度,我后头才发现,虽然这道题我高精度写的有点问题,但还是过了。
除法
除法分为除低精度和除高精度,我这就只记录除高精度的模板
高精除
#include<iostream>
#include<cstring>
#include<cstdio>
using namespace std;
#define maxn 1000
char input[maxn];
int a[maxn], b[maxn], c[maxn];
int shang[maxn], yu[maxn];
void print(int *shuzu){
for(int i = shuzu[0]; i >= 1; i --)
printf("%d", shuzu[i]);
printf("\n");
}
void getin(int *shuzu){
memset(input, 0, sizeof(input));
memset(shuzu, 0, sizeof(int)*maxn);
scanf("%s", input);
int n = strlen(input);
for(int i = 0; i < n; i ++)
shuzu[n-i] = input[i] - '0';
int i = n;
while(shuzu[i] == 0 && i > 1) i -- ;
shuzu[0] = i;
}
void sub(int *a, int *b){
for(int i = 1; i <= a[0]; i ++){
if(a[i] < b[i]){a[i+1] --; a[i] += 10;}
a[i] -= b[i];
}
int i = a[0];
while(a[i] == 0 && i > 1) i --;
a[0] = i;
}
bool compare(int *a, int *b){
if(a[0] > b[0]) return true;
if(a[0] < b[0]) return false;
int i = a[0];
while(i > 1 && a[i]==b[i]) i --;
if(a[i] >= b[i]) return true;
else return false;
}
void div(int *a, int *b, int *shang, int *yu){
memset(shang, 0, sizeof(int)*maxn);
memset(yu, 0, sizeof(int)*maxn);
int n = a[0];
for(int i = n; i >= 1; i --){
int arr[maxn];
memset(arr, 0, sizeof(arr));
memcpy(arr+i, b+1, sizeof(int)*b[0]);
arr[0] = b[0] + i - 1;
int temp = 0;
while(compare(a, arr)){
sub(a, arr);
temp ++;
}
shang[i] = temp;
}
memcpy(yu, a, sizeof(int)*maxn);
while(shang[n] == 0 && n>1) n --;
shang[0] = n;
}
int main(){
getin(a);
getin(b);
div(a, b, shang, yu);
print(shang);
print(yu);
return 0;
}
10000!的阶乘
这道题就不得不用高精度乘低精度,如果就直接用高精度乘高精度就超时。
回文数
一直出错,后头网上一查才反应过来,为十六进制的时候输入的就有A~F了。