Acsing基础算法day2--基础算法

1.高精度

c++中的sort是快排和插排的结合
sort(a,a+n);

c++中没有大整数类

1.常用类型

大整数位数<=106 a的大小<=10的9次方

  1. A-B
  2. A+B
  3. A/a
  4. A*a

2.思路

1.大整数存储:将大整数的每一位存在数组中
高位在前:低位在前?
低位在前(进位在末尾比较容易添加)

1.A+B:模拟手工算法的过程

Ai+Bi+进位

#include<vector>
const int N=1e6+10;//防止边界溢出
vector<int> add(vector<int> &a,vector<int> &b)//引用效率快,不引用就是将数组复制一遍
{
  vector<int> c;
  int t=0;
  for(int i=0;i<a.size()||i<b.size();i++)
  {
     if(i<a.size()) t+=a[i];
     if(i<b.size()) t+=b[i];
     c.push_back(t%10);
     t/=10;
  }
  if(t) c.push_back(t);//若还有进位,将进位存入
  return c;
}
int main()
{
  string a,b;//大数超过范围就用字符串来接受
  vector<int> A,B;
  cin>>a>>b;
  for(int i=a.size()-1;i>+0;i--) A.push_back(a[i]-'0')//字符与数字的ascii码相差‘0’,低位先存
  for(int i=a.size()-1;i>+0;i--) B.push_back(a[i]-'0')auto c=add(A,B);//编译器自动推断类型
  for(int i=0;i<c.size();i++) printf("%d",c[i]);
  return 0;

}

2.A-B 手工模拟减法过程

Ai-Bi-t(借位
1.<0 Ai-Bi-t+10(借位
2.>=0 Ai-Bi-t

1.A>=B 直接算
2. A<B -(B-A)

//判断A>B吗?
bool cmp(vector<int> &A,vector<int>&B)
{
   if(a.size()!=B.size()) return A.size()>B.size();
   else
   {  
      for(int i=A.size()-1;i>=0;i--)
      {
         if(A[i]!=B[i] return A.[i]>B.[i];
      }
   }
   return true;
}
 vector<int> sub(vector<int> &A,vector<int> &B)
 {
     // 已经确定A>B
     vector<int> c;
     int t=0;//借位
     for(int i=0;i<A.size();i++)
     {
        t=A[i]-t;
        if(i<B.size()) t-=B[i];//B[i]不为空时才减
        c.push_back((t+10)%10);//将t大于0小于0合二为一了
        if(t<0) t=1;//有借位
        else t=0;//无借位
     }
     while(c.size()>0 && c.back()==0) c.pop.back();//高位为0是不需要输出的,如112-110=002;数组中是200,只用输出2即可,所以将数组末尾的0删去
     
 }
int main()
{
  string a,b;
  vector<int> A,B;
  cin>>a>>b;
  for(int i=a.size()-1;i>+0;i--) A.push_back(a[i]-'0')//字符与数字的ascii码相差‘0’,低位先存
  for(int i=a.size()-1;i>+0;i--) B.push_back(a[i]-'0')if(cmp(A,B))
  {
     auto c=sub(A,B);//编译器自动推断类型
     for(int i=0;i<c.size();i++) printf("%d",c[i]);
  }
  else
  {
      auto c=sub(B,A);//编译器自动推断类型
      cout<<'-';
      for(int i=0;i<c.size();i++) printf("%d",c[i]);
  return 0;

}

A*b

思路

c[i]= (A[i]*b+t)%10//将b看作整体
t=(A[i]*b+t)/10 //进位

代码
vector<int> mul(vector<int> &A, int b)
{
   vector<int> c;
   int t=0;
   for(int i=0;i<A.size()||t;i++)
   {
       if(i<A.size()) t+=A[i]*b;
       c.push_back(t%10);//进位很大时要辗转取余
       t/=10;
    } 
}

A/b

思路

Ci=(r10+Ai)/b
r=(r
10+Ai)%b 高位余数

vector<int> div(vector<int> &a,int b,int &r)//r是余数
{
   vector<int> c;
   r=0;
   for(int i=a.size()-1;i>=0;i--)
   {
      r=r*10+a[i];
      c.push_back(r/b);
      r%=b;
   }
   reverse(c,begin(),c.end());// 将数组翻转,和加减乘除输出一致
   while(c.size()>0 && c.back()==0) c.pop.back();
   return c;
   
}

2. 前缀和

描述:已知数组a1 a2 a3 …an 求前缀和 Si=a1+a2+a3+…+ai
下标从1开始 ,方便处理边界,统一公式,S[0]=0

思路

如何求Si=S[i-1]+ai
作用:快速求原数组一段的和,[l,r] 的和 = S[r]-S[l-1],时间是O(n)

代码

const int N=1e10;
int s[N];
for(int i=0;i<N;i++)  s[i]=s[i-1]+a[i];

子矩阵和

  1. S[i, j] = 第i行j列格子左上部分所有元素的和:s[i][j]=s[i-1][j]+s[i][j-1]+a[i][j]
  2. 以(x1, y1)为左上角,(x2, y2)为右下角的子矩阵的和为:
    S[x2, y2] - S[x1 - 1, y2] - S[x2, y1 - 1] + S[x1 - 1, y1 - 1]

3.差分

描述

已知数组 a1,a2,a3…an
构造b1,b2…bn 使得ai=b1+b2+…+bi,b数组就是a数组的差分

思路

b1=a1
b2=a2-a1

给数组A区间[l, r]中的每个数加上c:B[l] += c, B[r + 1] -= c

差分矩阵

给以(x1, y1)为左上角,(x2, y2)为右下角的子矩阵中的所有元素加上c:
S[x1, y1] += c, S[x2 + 1, y1] -= c, S[x1, y2 + 1] -= c, S[x2 + 1, y2 + 1] += c

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值