昨天做一道DP的题(矩阵取数游戏),本来是很简单的,但是要用高精度,又不想用__int128水过去(谁让NOIP不让),于是自己打了一个小时,最后挂了。。。
于是本蒟蒻痛定思痛,感觉高精度还是重载运算符好用,就花了几个小时打了一个高精度模板:
/*采用重载运算符,压4位 支持高精数输入与输出、高精加(减)高精、高精乘低(高)精、高精除(模)低精、高精的比较 注意:暂不支持负数!!!*/ #include<cstdio> #include<cstring> #include<stack> #include<iostream> #include<algorithm> using namespace std; const int N=128,base=1e4;//base是压4位的基数 struct HP{ private: int a[N],len; inline void clear(){while(!a[len]&&len>1) --len;}//清除前导0 public: HP(){ //结构体初始化 memset(a,0,sizeof a);len=0; } /*以下是高精度的输入与输出*/ void init_i(int x) {//用int初始化高精度数 stack<char> st;string s; while(x){ st.push(x%10+'0'); x/=10; } while(!st.empty()) s+=st.top(),st.pop();//其实就是把int转换为string再调用init_s() init_s(s); } //注意因为是压4位的,所以输入和输出都要特殊处理 void init_s(string s){//用string初始化高精度数 int l=s.length(); for(int i=0;i<=l;++i){ int j=(l-i+3)/4; a[j]=(a[j]<<1)+(a[j]<<3)+(s[i]^48); } len=(l+3)/4; } void print(){//输出高精度数 printf("%d",a[len]); for(int i=len-1;i>0;--i) for(int j=base/10;j>0;j/=10) printf("%d",a[i]/j%10); puts(""); } /*以下是重载运算符*/ HP operator +(const HP &x){//高精加高精 HP res;res.len=max(len,x.len);int k=0; for(int i=1;i<=res.len;++i){ res.a[i]=a[i]+x.a[i]+k; k=res.a[i]/base; res.a[i]%=base; } if(k>0) res.a[++res.len]=k; return res; } HP operator -(const HP &x){//高精减高精(注意这里默认被减数大于减数,否则会出错) HP res=*this;//相当于用res拷贝被减数 for(int i=1;i<=len;++i){ res.a[i]-=x.a[i]; if(res.a[i]<0) --res.a[i+1],res.a[i]+=base; } res.clear(); return res; } HP operator *(const int &x){//高精乘低精 HP res=*this; for(int i=1;i<=len;++i) res.a[i]*=x; for(int i=1;i<=len;++i) res.a[i+1]+=res.a[i]/base,res.a[i]%=base; int &end=res.len; while(res.a[end+1]>0){++end;res.a[end+1]+=res.a[end]/base,res.a[end]%=base;} return res; } HP operator *(const HP &x){//高精乘高精 HP res;res.len=len+x.len; for(int i=1;i<=len;++i) for(int j=1;j<=x.len;++j){ res.a[i+j-1]+=a[i]*x.a[j]; res.a[i+j]+=res.a[i+j-1]/base; res.a[i+j-1]%=base; } res.clear(); return res; } HP operator /(const int &x){//高精除低精 HP res;res.len=len; int k=0; for(int i=len;i>0;--i){ k=k*base+a[i]; res.a[i]=k/x; k%=x; } res.clear(); return res; } int operator %(const int &x){//高精模低精 int k=0; for(int i=len;i>0;--i){ k=k*base+a[i]; k%=x; } return k;//其实跟高精除低精差不多的,只不过不用存res,返回的是k } bool operator <(const HP &x)const{//重载小于号 (可以仿造重载大于号) if(len==x.len){ int i; for(i=len;a[i]==x.a[i]&&i>1;--i); if(i>=1) return a[i] < x.a[i]; else return false; } else return len < x.len; } }; HP max(HP a,HP b){ if(a<b) return b; return a; } HP min(HP a,HP b){ if(a<b) return a; return b; } HP a,b,ans; string sa,sb; int main() { cin>>sa>>sb; a.init_s(sa);b.init_s(sb); ans=a*b; ans.print(); return 0; }
注意暂不支持负数,如果发现有bug欢迎指出。
想粘板子就粘吧,打得丑我承认,
2018-10-20