高精度算法整理

洛谷p1601
高精度加法

#include<iostream>//用字符串类处理长数 
#include<string>
using namespace std;
string add(string str1,string str2){
 string str;
 int len1=str1.length(),len2=str2.length();
 if(len1<len2){
  for(int i=1;i<=len2-len1;i++)
  str1="0"+str1;//让两个数一样长,两数对齐 
 } 
 else{
  for(int i=1;i<=len1-len2;i++)
  str2="0"+str2;
 }
 len1=str1.length();
 int cf=0,temp;
 for(int i=len1-1;i>=0;i--){  //从低位开始运算 
  temp=str1[i]-'0'+str2[i]-'0'+cf; 
  cf=temp/10;//cf为进位 
  temp%=10;
  str=char(temp+'0')+str;
 }
 if(cf!=0) str=char(cf+'0')+str;//进位不为零 
 return str;
}
int main(){
 string str1,str2;
 cin>>str1>>str2;
 cout<<add(str1,str2)<<endl;
 return 0;
}//缺陷是不能进行负数相加 

这是直接对字符串进行的处理,还可用数组。

#include<iostream>
#include<string>
using namespace std;
#define maxn 1050
string a,b;
int na[maxn],nb[maxn],ans[maxn];
int main(){
 cin>>a>>b;
 for(int i=a.size();i>0;i--) na[i]=a[a.size()-i]-'0';
 for(int i=b.size();i>0;i--) nb[i]=b[b.size()-i]-'0';
 int max1=max(a.size(),b.size());
 for(int i=1;i<=max1;i++){
  if(na[i]+nb[i]>=10){
   na[i+1]++;
   ans[i]=na[i]+nb[i]-10;
  }
  else ans[i]=na[i]+nb[i];
 }




 if(na[max1+1]!=0) cout<<na[max1+1];
 for(int i=max1;i>0;i--)
 cout<<ans[i];
 return 0;
}

还有一个从大佬那学来的超级方法,可以处理负数
高精度减法

#include<bits/stdc++.h
#define MAXN 10500 
using namespace std;
string a, b;

string _add(string a, string b)//高精度相加 (为底下a或b为负数相减做铺垫)这个都会吧。 
{
    string sum;
    int na[MAXN] = {0}, nb[MAXN] = {0}, ans[MAXN + 1] = {0}; 

    for(int i = a.size(); i > 0; i --)na[i] = a[a.size() - i] - '0';
    for(int i = b.size(); i > 0; i --)nb[i] = b[b.size() - i] - '0';

    int maxl = max(a.size(), b.size());
    for(int i = 1; i <= maxl; i ++)
    {
        ans[i + 1] = (ans[i] + na[i] + nb[i]) / 10;
        ans[i] = (ans[i] + na[i] + nb[i]) % 10; 
    }//相加 
    if(ans[maxl + 1] != 0)sum += "1";//特判 防止最大位进位 
    for(int i = maxl;i > 0; i --)sum += ans[i]+'0';
    return sum;
}

string _minus(string a, string b)
{
    int na[MAXN] = {0}, nb[MAXN] = {0}, ans[MAXN] = {0};
    string diff;

    if((a < b && a.size() <= b.size()) || b.size() > a.size())
        return "-" + _minus(b, a);

    for(int i = a.size(); i > 0; i --)na[i] = a[a.size() - i] - '0';
    for(int i = b.size(); i > 0; i --)nb[i] = b[b.size() - i] - '0';

    int maxl = max(a.size(), b.size());

    for(int i = 1; i <= maxl; i ++)
    {
        if(na[i] < nb[i])
        {
            na[i + 1] --;
            na[i] += 10;
        }
        ans[i] = na[i] - nb[i];
    }
    while(ans[maxl] == 0)maxl --;//防止减后降位,多输出若干0
    if(maxl < 1)return "0";
    for(int i = maxl; i > 0; i --)diff += ans[i] + '0';//数组转化为字符串。 
    return diff;
}

int main()
{
    string a,b;
    cin >> a >> b;
    if(a[0] == '-' && b[0] == '-')  //当两个数字为负数 
    {
        a.erase(0, 1);
        b.erase(0, 1);//擦掉a,b打头的负号再运算,下同
        cout << _minus(b,a);    //-a-(-b)=-a+b=b-a 
        return 0;
    }
    else if(a[0] == '-')  //只有a为负数 
    {
        a.erase(0, 1);
        cout << "-" << _add(a, b);  //-a-b=-(a+b)
        return 0;
    }
    else if(b[0] == '-')  //只有b为负数 
    {
        b.erase(0, 1);
        cout << _add(a, b);  //a-(-b)=a+b 
        return 0;
    } 
    else cout << _minus(a, b);
    return 0;
}

高精度乘法

#include<iostream>
#include<string>
using namespace std;
#define maxn 10050
int na[maxn],nb[maxn],c[maxn];
int main(){
 string a,b;
 cin>>a>>b;
 for(int i=a.size();i>0;i--) na[i]=a[a.size()-i]-'0';
 for(int i=b.size();i>0;i--) nb[i]=b[b.size()-i]-'0';
 for(int i=1;i<=a.size();i++)
 {
  for(int j=1;j<=b.size();j++)
  c[i+j-1]+=na[i]*nb[j];
 }
     int len=a.size()+b.size();
     for(int i=1;i<len;i++) if(c[i]>9){c[i+1]+=c[i]/10;c[i]=c[i]%10;}
     while(c[len]==0&&len>1) len--;
     for(int i=len;i>0;i--) cout<<c[i];
     return 0;
} 

高精度除法暂时还不会。。

洛谷对角线

  • 四边形的个数
#include<cstdio>
#include<iostream>
using namespace std;
int main()
{
    unsigned long long n;
    cin>>n;
    cout<<(n*(n-1)/2*(n-2)/3*(n-3)/4)<<endl;
    return 0;
}

素数
素数模板

bool is_prime(int n){
int m=floor(sqrt(n)+0.5);
for(int i=2;i<=m;i++)
if(n%i==0) return false;
return true;
}

埃尼斯托尼斯筛法

int prime[maxn];
void prime(int maxn){
for(int i=0;i<maxn;i++) prime[i]=1;//先把每个数设为素数
prime[0]=prime[1]=0;
for(int i=2;i<maxn;i++){
 if(prime[i])
 for (int j=i*2; j<MAXN; j+=i) prime[j] = 0;  //将i的倍数标记为合数
}
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值