文章目录
- 高精度 + 高精度
- 高精度 - 高精度
- 高精度 * 高精度
- 高精度 * 单精度
- 高精度 / 单精度
- 高精度幂取模
- 高精度取余
高精度 + 高精度
?题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1002 ?晕,初始化数组写错,wa几次才发现.这里需要注意的是输出的时候注意最后一位的进位.
//大数加法模板(求两个非负的高精度整数相加的和)
#include
#include
#include
#include
using namespace std;
const int Max_n=1005;
typedef long long LL;
int a[Max_n],b[Max_n];
char c[Max_n],d[Max_n];
int main(){
int t;
scanf("%d",&t);
for(int cnt=1;cnt<=t;cnt++){
memset(a,0,sizeof(a));
memset(b,0,sizeof(b));
scanf("%s%s",c,d);
int lenc=strlen(c);
for(int i=0;i<lenc;i++)
a[i]=c[lenc-i-1]-'0';
int lend=strlen(d);
for(int i=0;i<lend;i++)
b[i]=d[lend-i-1]-'0';
int len=max(lenc,lend);
for(int i=0;i<len;i++){
a[i]=a[i]+b[i];
if(a[i]>9){
a[i]-=10;
a[i+1]++;
}
}
printf("Case %d:\n",cnt);
printf("%s + %s = ",c,d);
len=a[len]?len:len-1;//这里要注意进位的问题
for(int i=len;i>=0;i--)
printf("%d",a[i]);
printf("\n");
if(cnt<t) printf("\n");
}
return 0;
}
高精度 - 高精度
?题目链接:http://tk.hustoj.com/problem.php?id=22598 ?
//求两个高精度正整数(x,y)相减的,如果x
#include
#include
#include
#include
using namespace std;
const int Max_n=10005;
typedef long long LL;
int a[Max_n],b[Max_n];
string c,d;
bool cmp(){
if(c.length()!=d.length())
return c.length()>d.length();
return c>=d;
}
int main(){
cin>>c>>d;
int lenc=c.length();
int lend=d.length();
if(cmp()){
for(int i=0;i<lenc;i++)
a[i]=c[lenc-i-1]-'0';
for(int i=0;i<lend;i++)
b[i]=d[lend-i-1]-'0';
}else{
for(int i=0;i<lend;i++)
a[i]=d[lend-i-1]-'0';
for(int i=0;i<lenc;i++)
b[i]=c[lenc-i-1]-'0';
cout<<"-";
}
int len=max(lenc,lend);
for(int i=0;i<len;i++){
if(a[i]>=b[i]) a[i]-=b[i];
else{
a[i]=a[i]+10-b[i];
a[i+1]--;
}
}
int index=-1;
for(int i=len-1;i>0;i--){//可以借助高精度/单精度里面的方法去除前导0(要比这个简单很多).
if(a[i]){
index=i;
break;
}
}
if(index!=-1){
for(int i=index;i>=0;i--)
cout<<a[i];
cout<<endl;
}else cout<<"0"<<endl;
return 0;
}
?题目链接:http://acm.sdut.edu.cn/onlinejudge2/index.php/Home/Index/problemdetail/pid/2525.html ?
此题怎么也过不去,不知道为什么.有做出来的可以交流交流(一定是我写的板子太弱了).
高精度 * 高精度
?题目链接:http://www.51nod.com/Challenge/Problem.html#!#problemId=1027 ?
?题目链接:http://tk.hustoj.com/problem.php?id=22599 ?
//首先计算被乘数与乘数的每位数字的乘积,其中a[i]乘b[j]的积 累加到数组ans[i+j]上,然后对累加结果ans作一次性进位.
#include
#include
#include
#include
using namespace std;
const int Max_n=1005;
typedef long long LL;
int a[Max_n],b[Max_n],ans[2*Max_n];//保存的最大位数就是lena+lenb
char c[Max_n],d[Max_n];
int main(){
scanf("%s%s",c,d);
int lenc=strlen(c);
for(int i=0;i<lenc;i++)
a[i]=c[lenc-i-1]-'0';
int lend=strlen(d);
for(int i=0;i<lend;i++)
b[i]=d[lend-i-1]-'0';
for(int i=0;i<lenc;i++)
for(int j=0;j<lend;j++)
ans[i+j]+=a[i]*b[j];//注意'+'
int len=lenc+lend;//最多len位(从0开始取到的就是a[len-1]),无进位就是len-1(a[len-2])位
for(int i=0;i<len-1;i++){
if(ans[i]>9){
ans[i+1]+=ans[i]/10;//抽出个位以外的数字
ans[i]%=10;//保留个位
}
}
len=ans[len-1]?len-1:len-2;//下标最多到len-1
for(int i=len;i>=0;i--)
printf("%d",ans[i]);
printf("\n");
return 0;
}
高精度 * 单精度
?题目链接:http://www.dotcpp.com/oj/problem1474.html ?
//只够大内存(不普遍适用)
#include
#include
#include
#include
using namespace std;
const int Max_n=4*1005;
typedef long long LL;
struct BigNum{
int s[Max_n],l;
}c[1005];
BigNum operator *(BigNum a,int b){
for(int i=0;i<a.l;i++) a.s[i]*=b;
for(int i=0;i<a.l;i++){//(除最高位)处理各个位上面的数
a.s[i+1]+=a.s[i]/10;
a.s[i]%=10;
}
while(a.s[a.l]!=0){//处理最高位
a.s[a.l+1]+=a.s[a.l]/10;
a.s[a.l]%=10;
a.l++;
}
return a;
}
void print(BigNum a){
for(int i=a.l-1;i>=0;i--)
printf("%d",a.s[i]);
printf("\n");
}
int main(){
c[0].s[0]=1,c[0].l=1;
for(int i=1;i<=1000;i++)
c[i]=c[i-1]*i;
int n;
scanf("%d",&n);
print(c[n]);
return 0;
}
高精度 / 单精度
//与下面的大数取余原理差不多
//示例1:
BigNum operator /(BigNum a,int b){
for(int i=a.l-1;i>0;i--){//从最高位开始处理
a.s[i-1]+=(a.s[i]%b)*10;
a.s[i]/=b;
}
a.s[0]/=b;
while(a.s[a.l-1]==0) a.l--;//去除前导0
return a;
}
//示例2:
int main(){//计算1234/8
int n=4;
int a[4]={4,3,2,1};
for(int i=n-1;i>0;i--){
a[i-1]+=(a[i]%8)*10;
a[i]/=8;
}
a[0]/=8;
while(a[n-1]==0) n--;
for(int i=n-1;i>=0;i--)
printf("%d",a[i]);
printf("\n");
return 0;
}
高精度幂取模
?题目链接:https://ac.nowcoder.com/acm/contest/392/B ?
#include
#include
#include
#include
#include
using namespace std;
const int Max_n=100005;
typedef long long LL;
LL q_mul(LL a,LL b,LL mod){//快速乘
LL ans=0,res=a;
while(b){
if(b&1) ans=(ans+res)%mod;
res=(res+res)%mod;
b>>=1;
}
return ans;
}
LL q_pow(LL a,LL b,LL mod){//快速幂
LL ans=1,res=a;
while(b){
if(b&1) ans=q_mul(ans,res,mod);
res=q_mul(res,res,mod);
b>>=1;
}
return ans;
}
int main(){
int t;
scanf("%d",&t);
while(t--){
LL a,b,mod;
scanf("%lld%lld%lld",&a,&b,&mod);
LL ans=q_pow(a,b,mod);
printf("%lld\n",ans);
}
return 0;
}
高精度取余
?总结链接:https://blog.csdn.net/qq_42217376/article/details/86722805 ?
//大数取余
LL Qpow_mod(){
LL ans=0;
int n=strlen(a);
for(int i=0;i<n;i++)
ans=(ans*10+(a[i]-'0'))%mod;
return ans;
}
int main(){
scanf("%s",a);
LL b=Qpow_mod();
printf("%lld\n",b);
return 0;
}