本代码支持:
重载运算符 + - * / %
正负整数(%没有)
全高精度
我菜狗我直接放代码:
#include<bits/stdc++.h>
#define ll long long
using namespace std;
namespace Bigint{
const int maxn=2e4+2;
struct bigint{
int len, a[maxn]; bool symbol;
// 数字长度, 数字, 符号
//初始化
bigint(int x=0)
{
if(x>=0) symbol=true;
else symbol=false,x=-x;
memset(a,0,sizeof(a));
for(len=1;x;++len)
{
a[len]=x%10,
x/=10;
}
--len;
}
//重载运算符[],使调用数位更方便
int &operator [](int i)
{
return a[i];
}
//字符串输入(当然,也可以用快读读入string)
void in()
{
string s;
cin>>s;
len=s.size();
for(int i=len-1;i>=1;--i)
{
a[len-i]=s[i]-'0';
}
if(s[0]=='-') symbol=false,--len;
else a[len]=s[0]-'0';
}
//进位并去除前导0
void flatten(int l)
{
len=l;
for(int i=1;i<=len;++i)
{
a[i+1]+=a[i]/10;
a[i]%=10;
}
for(;!a[len];--len);
}
//借位(?并实现前导0
//减法最后再借位也不是不行,只要借的到
void flatten_(int l)
{
len=l;
for(int i=1;i<=len;++i)
{
if(a[i]<0)
{
--a[i+1],
a[i]+=10;
}
}
for(;!a[len];--len);
}
//输出
void out()
{
if(!symbol&&len>=1) printf("-");//还要防止出现-0
for(int i=max(len,1);i>=1;--i)
{
printf("%d",a[i]);
}
}
};
bool compare(bigint x,bigint y)
{
//If x>=y,return true.
bool flag=true;
if(x.len<y.len) return false;
else
if(x.len==y.len)
{
for(int i=x.len;i>=1;--i)
{
if(y[i]<x[i]) return true;
if(y[i]>x[i]) return false;
}
}
return true;
}
bigint plus(bigint x,bigint y)// '+'
{
bigint res;
res.len=max(x.len,y.len);
for(int i=1;i<=res.len;++i)
{
res[i]+=x[i]+y[i];
// 等价于 res.a[i]+=a.a[i]+b.a[i];
// 这就是重载[]的作用了
}
res.flatten(res.len+1);
return res;
}
bigint minus(bigint x,bigint y)// '*'
{
bigint res;
res.len=x.len;
for(int i=1;i<=res.len;++i)
{
res[i]+=x[i]-y[i];
}
res.flatten_(res.len);
return res;
}
bigint multiply(bigint x,bigint y)// '*'
{
bigint res;int len=x.len+y.len;
for(int i=1;i<=x.len;++i)
{
for(int j=1;j<=y.len;++j)
{
res[i+j-1]+=x[i]*y[j];
}
}
res.flatten(len+1);
return res;
}
bigint divide_by(bigint x,bigint y)// '/'
{
//The division based on subtraction.
//懒得打试除法了,直接用减法一点点减
bigint res;res.len=x.len;
for(int tail=x.len-y.len;tail>=0;--tail)
{
while(true)
{
bool flag=false;
for(int i=y.len;i>=1;--i)
{
if(x[i+tail]>y[i]) break;
if(x[i+tail]<y[i])
{
flag=true;
break;
}
}
if(flag) break;
for(int i=y.len;i>=1;--i)
{
x[i+tail]-=y[i];
}
++res[tail+1];
x.flatten_(x.len);
}
x[y.len+tail-1]+=x[y.len+tail]*10;
x[y.len+tail]=0;
}
res.flatten(res.len);
return res;
}
bigint mod_by(bigint x,bigint y)// '%'
{
int len=x.len;
for(int tail=x.len-y.len;tail>=0;--tail)
{
while(true)
{
bool flag=false;
for(int i=y.len;i>=1;--i)
{
if(x[i+tail]>y[i]) break;
if(x[i+tail]<y[i])
{
flag=true;
break;
}
}
if(flag) break;
for(int i=y.len;i>=1;--i)
{
x[i+tail]-=y[i];
}
x.flatten_(x.len);
}
x[y.len+tail-1]+=x[y.len+tail]*10;
x[y.len+tail]=0;
}
x.flatten_(len+1);
x.flatten(len+1);
return x;//返回剩下的就是余数了
}
//以上操作只适用于正整数,对正负的判断在下面的重载函数中
bigint operator -(bigint x,bigint y)
{
bigint res;
if(compare(x,y)) res=minus(x,y);
else res=minus(y,x),res.symbol=false;
return res;
}
//O(len)
bigint operator +(bigint x,bigint y)
{
if(x.symbol&&!y.symbol) return x-y;
if(!x.symbol&&y.symbol) return y-x;
if(!x.symbol)
{
bigint res;
res=plus(x,y),
res.symbol=false;
return res;
}
return plus(x,y);
}
//O(len)
bigint operator *(bigint x,bigint y)
{
bigint res;
res=multiply(x,y);
if(x.symbol^y.symbol) res.symbol=false;
return res;
}
//O(len^2)
bigint operator /(bigint x,bigint y)
{
bigint res;
res=divide_by(x,y);
if(x.symbol^y.symbol) res.symbol=false;
return res;
}
//O(len^2)
bigint operator %(bigint x,bigint y)
{
//Only positive number.
return mod_by(x,y);
}
//O(len^2)
}
using namespace Bigint;
bigint a,b,c;
signed main()
{
// a.in();b.in();
// c=a+b;
// c.out();puts("");
// c=a-b;
// c.out();puts("");
// c=a*b;
// c.out();puts("");
// c=a/b;
// c.out();puts("");
// c=a%b;
// c.out();puts("");
return 0;
}
%的只是把除法代码改了下。。
实测可过 洛谷:P1932 A+B A-B A*B A/B A%B Problem
毕竟花了一整天还多。。今天想争取把浮点数搞定。