一、
791. 高精度加法
给定两个正整数(不含前导 00),计算它们的和。
输入格式
共两行,每行包含一个整数。
输出格式
共一行,包含所求的和。
数据范围
1≤整数长度≤1000001≤整数长度≤100000
输入样例:
12
23
输出样例:
35
思路:
使用t来记录进位,考虑a,b的数位大小,我的思路为a>b;还有几个注意点,使用string输入,并将每一位其转化为int存在a,b中,主要以个位到首位这样存储,也是从个位到首位这样加。
vector<int> add(vector<int>&a,vector<int>&b)
{
if(a.size()<b.size())
{
return add(b,a);
}
int t=0;
vector<int>c;
for(int i=0;i<a.size();i++)
{
t+=a[i];
if(i<b.size())t+=b[i];
c.push_back(t%10);
t/=10;
}
if(t)c.push_back(1);
return c;
}
int main()
{
vector<int> a,b;
string A,B;
cin>>A>>B;
for(int i=A.size()-1;i>=0;i--)
{
a.push_back(A[i]-'0');
}
for(int i=B.size()-1;i>=0;i--)
{
b.push_back(B[i]-'0');
}
auto c=add(a,b);
for(int i=c.size()-1;i>=0;i--)
{
cout<<c[i];
}
return 0;
}
---------------------------------------------------------------------------------------------------------------------------------
二、高精度减法
792. 高精度减法
给定两个正整数(不含前导 00),计算它们的差,计算结果可能为负数。
输入格式
共两行,每行包含一个整数。
输出格式
共一行,包含所求的差。
数据范围
1≤整数长度≤1051≤整数长度≤105
输入样例:
32
11
输出样例:
21
思路:
1.若a>b,则直接调用a-b;若a<b,则调用b-a取负号;
2.使用t记录进位
3.编写比较a,b数组函数cmp
4.记得弹出头位的0
5.注意当i>=b.size()时,不减去b[i],因为已经超格
bool cmp(vector<int>&a,vector<int>&b)
{
if(a.size()!=b.size())return a.size()>b.size();
for(int i=a.size()-1;i>=0;i--)
{
if(a[i]!=b[i])return a[i]>b[i];
}
return true;
}
vector<int> jian(vector<int> &a,vector<int>&b)
{
vector<int>c;
int t=0;
for(int i=0;i<a.size();i++)
{
t=a[i]-t;
if(i<b.size())t=t-b[i];
c.push_back((t+10)%10);
t=t>=0?0:1;
}
while(c.size()>1&&c.back()==0)c.pop_back();
return c;
}
int main()
{
vector<int> a,b;
string A,B;
cin>>A>>B;
for(int i=A.size()-1;i>=0;i--)
{
a.push_back(A[i]-'0');
}
for(int i=B.size()-1;i>=0;i--)
{
b.push_back(B[i]-'0');
}
if(cmp(a,b))
{
auto c=jian(a,b);
for(int i=c.size()-1;i>=0;i--)
{
cout<<c[i];
}
}
else
{
auto c=jian(b,a);
cout<<"-";
for(int i=c.size()-1;i>=0;i--)
{
cout<<c[i];
}
}
return 0;
}
--------------------------------------------------------------------------------------------------------------------------------
三、高精度乘法
793. 高精度乘法
给定两个非负整数(不含前导 00) AA 和 BB,请你计算 A×BA×B 的值。
输入格式
共两行,第一行包含整数 AA,第二行包含整数 BB。
输出格式
共一行,包含 A×BA×B 的值。
数据范围
1≤A的长度≤1000001≤A的长度≤100000,
0≤B≤100000≤B≤10000
输入样例:
2
3
输出样例:
6
思路:
1.让大数A每个数位成小数值b,用t记录进了多少位,在下一位乘的时候加上即可
2.因为遍历完a.size()时,t的结果还有进位没有加,加上即可;
vector<int> cheng(vector<int> &a,int b)
{
vector<int> c;
if(b==0)
{
c.push_back(0);
return c;
}
int t=0;
for(int i=0;i<a.size();i++)
{
t=t+a[i]*b;
c.push_back(t%10);
t=t/10;
}
while(t!=0)
{
c.push_back(t%10);
t/=10;
}
return c;
}
int main()
{
vector<int>A;
string a;
int b;
cin>>a>>b;
for(int i=a.size()-1;i>=0;i--)
{
A.push_back(a[i]-'0');
}
auto c=cheng(A,b);
for(int i=c.size()-1;i>=0;i--)
{
cout<<c[i];
}
return 0;
}
---------------------------------------------------------------------------------------------------------------------------------
四、高精度除法
794. 高精度除法
给定两个非负整数(不含前导 00) A,BA,B,请你计算 A/BA/B 的商和余数。
输入格式
共两行,第一行包含整数 AA,第二行包含整数 BB。
输出格式
共两行,第一行输出所求的商,第二行输出所求余数。
数据范围
1≤A的长度≤1000001≤A的长度≤100000,
1≤B≤100001≤B≤10000,
BB 一定不为 00
输入样例:
7
2
输出样例:
3
1
思路:
1.从最高位开始除,除不尽剩下的r和第二高位结合为r=r*10+a[i];反复此动作即可;
2.注意:除法是从A数组最高位开始做运算;
#include<iostream>
using namespace std;
#include<vector>;
#include<bits/stdc++.h>
int r=0;
vector<int> chu(vector<int> &a,int b)
{
vector<int> c;
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()>1&&c.back()==0)c.pop_back();
return c;
}
int main()
{
vector<int>A;
string a;
int b;
cin>>a>>b;
for(int i=a.size()-1;i>=0;i--)
{
A.push_back(a[i]-'0');
}
auto c=chu(A,b);
for(int i=c.size()-1;i>=0;i--)
{
cout<<c[i];
}
cout<<endl<<r;
return 0;
}
--------------------------------------------------------------------------------------------------------------------------------五、前缀和
795. 前缀和
输入一个长度为 nn 的整数序列。
接下来再输入 mm 个询问,每个询问输入一对 l,rl,r。
对于每个询问,输出原序列中从第 ll 个数到第 rr 个数的和。
输入格式
第一行包含两个整数 nn 和 mm。
第二行包含 nn 个整数,表示整数数列。
接下来 mm 行,每行包含两个整数 ll 和 rr,表示一个询问的区间范围。
输出格式
共 mm 行,每行输出一个询问的结果。
数据范围
1≤l≤r≤n1≤l≤r≤n,
1≤n,m≤1000001≤n,m≤100000,
−1000≤数列中元素的值≤1000−1000≤数列中元素的值≤1000
输入样例:
5 3
2 1 3 6 4
1 2
1 3
2 4
输出样例:
3
6
10
思路:
1.第一项为s[0]=0;
2.s[k]=s[k-1]+a[i]
#include<iostream>
using namespace std;
#include<vector>;
#include<bits/stdc++.h>
int main()
{
int n,m;
scanf("%d %d",&n,&m);
vector<int> a(n);
int s[n+1];
s[0]=0;
for(int i=0;i<n;i++)
{
scanf("%d",&a[i]);
s[i+1]=s[i]+a[i];
}
while(m--)
{
int k,v;
scanf("%d %d",&k,&v);
printf("%d\n",s[v]-s[k-1]);
}
return 0;
}
---------------------------------------------------------------------------------------------------------------------------------六、
796. 子矩阵的和
输入一个 nn 行 mm 列的整数矩阵,再输入 qq 个询问,每个询问包含四个整数 x1,y1,x2,y2x1,y1,x2,y2,表示一个子矩阵的左上角坐标和右下角坐标。
对于每个询问输出子矩阵中所有数的和。
输入格式
第一行包含三个整数 n,m,qn,m,q。
接下来 nn 行,每行包含 mm 个整数,表示整数矩阵。
接下来 qq 行,每行包含四个整数 x1,y1,x2,y2x1,y1,x2,y2,表示一组询问。
输出格式
共 qq 行,每行输出一个询问的结果。
数据范围
1≤n,m≤10001≤n,m≤1000,
1≤q≤2000001≤q≤200000,
1≤x1≤x2≤n1≤x1≤x2≤n,
1≤y1≤y2≤m1≤y1≤y2≤m,
−1000≤矩阵内元素的值≤1000−1000≤矩阵内元素的值≤1000
输入样例:
3 4 3
1 7 2 4
3 6 2 8
2 1 2 3
1 1 2 2
2 1 3 4
1 3 3 4
输出样例:
17
27
21
思路:
1.首先,定义s[n+1][m+1]数组,将其全部赋值为0;
2.将第二行第二列进行第五题的前缀和赋值;
3.如何求s[i][j]? s[i][j]=a[i-1][j-1]-s[i-1][j-1]+s[i][j-1]+s[i-1][j];因为s比a整体每一行列多1;
4.如何求和?t=s[x2][y2]+s[x1-1][y1-1]-s[x1-1][y2]-s[x2][y1-1];记住不要将x1,y1放在被减的列表里;
#include<iostream>
using namespace std;
#include<vector>;
#include<bits/stdc++.h>
int main()
{
int n,m,q;
scanf("%d %d %d",&n,&m,&q);
int a[n][m];
int s[n+1][m+1];
for(int i=0;i<n;i++)
{
for(int j=0;j<m;j++)
{
scanf("%d",&a[i][j]);
}
}
for(int i=0;i<=n;i++)
{
for(int j=0;j<=m;j++)
{
s[i][j]=0;
}
}
s[1][1]=a[0][0];
for(int i=1;i<=n;i++)
{
s[i][1]=s[i-1][1]+a[i-1][0];
}
for(int i=1;i<=m;i++)
{
s[1][i]=s[1][i-1]+a[0][i-1];
}
//cout<<endl;
for(int i=1;i<=n;i++)
{
for(int j=1;j<=m;j++)
{
s[i][j]=a[i-1][j-1]-s[i-1][j-1]+s[i][j-1]+s[i-1][j];
}
}
/*for(int i=0;i<n+1;i++)
{
for(int j=0;j<m+1;j++)
{
cout<<s[i][j]<<" ";
}
cout<<endl;
}*/
while(q--)
{
int x1,y1,x2,y2;
scanf("%d %d %d %d",&x1,&y1,&x2,&y2);
int t=s[x2][y2]+s[x1-1][y1-1]-s[x1-1][y2]-s[x2][y1-1];
printf("%d\n",t);
}
return 0;
}
---------------------------------------------------------------------------------------------------------------------------------
七、
797. 差分
输入一个长度为 nn 的整数序列。
接下来输入 mm 个操作,每个操作包含三个整数 l,r,cl,r,c,表示将序列中 [l,r][l,r] 之间的每个数加上 cc。
请你输出进行完所有操作后的序列。
输入格式
第一行包含两个整数 nn 和 mm。
第二行包含 nn 个整数,表示整数序列。
接下来 mm 行,每行包含三个整数 l,r,cl,r,c,表示一个操作。
输出格式
共一行,包含 nn 个整数,表示最终序列。
数据范围
1≤n,m≤1000001≤n,m≤100000,
1≤l≤r≤n1≤l≤r≤n,
−1000≤c≤1000−1000≤c≤1000,
−1000≤整数序列中元素的值≤1000−1000≤整数序列中元素的值≤1000
输入样例:
6 3
1 2 2 1 2 1
1 3 1
3 5 1
1 6 1
输出样例:
3 4 5 3 4 2
思路:
1.求出差分数组chafen(),chafen(i,i,a[i]);;
2.将b变为自己的后缀和数组
3.输出b
#include<iostream>
using namespace std;
#include<vector>;
#include<bits/stdc++.h>
int a[100000],b[100000];
void chafen(int l,int r,int k)
{
b[l]+=k;
b[r+1]-=k;
}
int main()
{
int n,m;
cin>>n>>m;
for(int i=0;i<n;i++)
{
cin>>a[i];
}
for(int i=0;i<n;i++)
{
chafen(i,i,a[i]);
}
while(m--)
{
int l,r,k;
cin>>l>>r>>k;
chafen(l-1,r-1,k);
}
for(int i=1;i<n;i++)b[i]=b[i-1]+b[i];
for(int i=0;i<n;i++)cout<<b[i]<<" ";
}
---------------------------------------------------------------------------------------------------------------------------------
八、
798. 差分矩阵
输入一个 nn 行 mm 列的整数矩阵,再输入 qq 个操作,每个操作包含五个整数 x1,y1,x2,y2,cx1,y1,x2,y2,c,其中 (x1,y1)(x1,y1) 和 (x2,y2)(x2,y2) 表示一个子矩阵的左上角坐标和右下角坐标。
每个操作都要将选中的子矩阵中的每个元素的值加上 cc。
请你将进行完所有操作后的矩阵输出。
输入格式
第一行包含整数 n,m,qn,m,q。
接下来 nn 行,每行包含 mm 个整数,表示整数矩阵。
接下来 qq 行,每行包含 55 个整数 x1,y1,x2,y2,cx1,y1,x2,y2,c,表示一个操作。
输出格式
共 nn 行,每行 mm 个整数,表示所有操作进行完毕后的最终矩阵。
数据范围
1≤n,m≤10001≤n,m≤1000,
1≤q≤1000001≤q≤100000,
1≤x1≤x2≤n1≤x1≤x2≤n,
1≤y1≤y2≤m1≤y1≤y2≤m,
−1000≤c≤1000−1000≤c≤1000,
−1000≤矩阵内元素的值≤1000−1000≤矩阵内元素的值≤1000
输入样例:
3 4 3
1 2 2 1
3 2 2 1
1 1 1 1
1 1 2 2 1
1 3 2 3 2
3 1 3 4 1
输出样例:
2 3 4 1
4 3 4 1
2 2 2 2
思路:
1.由图,将b[i][j]+c时,对应是s(1,2,3,4)区域全部加c,此时要减去s(2,4)和s(3,4)的值并且加上s4的值即可。即对应:
b[x1][y1]+=k;
b[x2+1][y2+1]+=k;
b[x1][y2+1]-=k;
b[x2+1][y1]-=k;
当chafen(i,j,i,j,a[i][j])时,可以理解为将大矩形缩成一个格子求得b[i][j]
2.最后,使用前缀和b[i][j]+=b[i-1][j]+b[i][j-1]-b[i-1][j-1]将b本身变成前缀和函数,再对应输出即可;
#include<iostream>
using namespace std;
#include<vector>;
#include<bits/stdc++.h>
int a[1010][1010],b[1010][1010];
void chafen(int x1,int y1,int x2,int y2,int k)
{
b[x1][y1]+=k;
b[x2+1][y2+1]+=k;
b[x1][y2+1]-=k;
b[x2+1][y1]-=k;
}
int main()
{
int n,m,q;
cin>>n>>m>>q;
for(int i=1;i<=n;i++)
{
for(int j=1;j<=m;j++)
{
cin>>a[i][j];
}
}
for(int i=1;i<=n;i++)
{
for(int j=1;j<=m;j++)
{
chafen(i,j,i,j,a[i][j]);
}
}
while(q--)
{
int x1,y1,x2,y2,c;
cin>>x1>>y1>>x2>>y2>>c;
chafen(x1,y1,x2,y2,c);
}
for(int i=1;i<=n;i++)
{
for(int j=1;j<=m;j++)
{
b[i][j]+=b[i-1][j]+b[i][j-1]-b[i-1][j-1];
}
}
for(int i=1;i<=n;i++)
{
for(int j=1;j<=m;j++)
{
cout<<b[i][j]<<" ";
}
cout<<endl;
}
return 0;
}