背书是万能的,不够聪明就背它个十万八千次! 0-0!
AcWing 785. 快速排序
C++
#include
using namespace std;
const int N = 100005;
int n;
int a[N];
// 板子是老师的 但是我写成while的形式...
void quick_sort(int q[],int l,int r)
{
if(l>=r) return;//截断只有一个数的情况
int x = q[l+r>>1],i = l-1, j = r+1;//防止溢出
while(ix);
if(i
AcWing 786. 第k个数
快排的迅速判断,只用递归一边就可以达成
C++
#include
using namespace std;
const int N= 100005;
int n,k;
int a[N];
int quick_select(int q[],int l,int r,int k)
{
if(l==r) return q[l];
int x = q[l+r>>1], i = l-1, j = r+1;
while(ix);
if(i
AcWing 787. 归并排序
C++
#include
using namespace std;
// #define N 1000010
const int N = 1000010;
int tmp[N];
void merge_sort(int q[],int l,int r)
{
//先特殊判断
if(l>=r) return;
// 分界点x
int mid = l+r>>1;
//递归
merge_sort(q,l,mid);
merge_sort(q,mid+1,r);
//分块2个数组 i:l-mid,j:mid+1-r
int k =0, i = l, j = mid+1;
while(i<=mid && j<=r)
{
if(q[i]<=q[j]) tmp[k++] = q[i++];
else tmp[k++] = q[j++];
}
// 剩余的数据移过来... 谁剩下了就移过来...
while(i<=mid) tmp[k++] = q[i++];
while(j<=r) tmp[k++] = q[j++];
//赋值
for(i=l,j=0;i<=r;i++,j++) q[i] = tmp[j];
}
int main()
{
int n;
scanf("%d",&n);
int a[n];
for(int i=0;i
AcWing 789. 数的范围 二分
还是背书快,但是理解的话画画图吧,这样才能理解,单纯背还是不得要领。
C++
//https://blog.csdn.net/m0_46680603/article/details/119137088
// 对抗难题的最好方式就是背下来所有的答案
// 二分实在不会就背吧..
#include
using namespace std;
int main()
{
int n,m,k;
cin>>n>>m;
int a[n];
for(int i=0;i>a[i];
for(int p=0;p=x
while(l>1;
if(a[mid]>=k)
r = mid;
else l = mid + 1;
}
if(a[l]!=k) cout<<"-1 -1"<>1;
if(a[mid]<=k) l = mid;
else r = mid - 1;
}
if(a[l]!=k) cout<<"-1 -1"<
前缀和和差分系列
AcWing 795. 前缀和
#include
using namespace std;
const int N = 100005;
int n, m;
int b[N],a[N];
int main()
{
cin>>n>>m;
for(int i=1;i<=n;i++) cin>>a[i];
for(int i=1;i<=n;i++)
{
b[i] = b[i-1]+a[i];
}
int l,r;
for(int i=0;i>l>>r;
cout<
AcWing 796. 子矩阵的和
//https://www.acwing.com/video/239/
// 接受两个坐标询问子矩阵的和 (x1,y1) (x2,y2)
// s[i][j] 的含义: a[0-i][0-j]的和 a[i][j]这个点左上角的区域,包含这个点
// 如何计算 以左上角 (x1,y1) 右下角 (x2,y2) 子矩阵里面所有的和
// 画格子图理解会好一些...
// target= s[x2,y2]-s[x1-1,y2]-s[x2,y1-1]+s[x1-1,y1-1]
// 其中s[x1-,y1-1]被减两次要加回来一次
// s 是子矩阵前缀和
// s[i,j] = s[i-1,j]+s[i,j-1]-s[i-1,j-1]+a[i,j]
#include
using namespace std;
int n,m,q;
const int N=1010;
int a[N][N],s[N][N];
int main()
{
scanf("%d%d%d",&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++)
{
s[i][j] = s[i-1][j]+s[i][j-1]-s[i-1][j-1]+a[i][j];
}
while(q--)
{
int x1,x2,y1,y2;
scanf("%d%d%d%d",&x1,&y1,&x2,&y2);
printf("%d\n",s[x2][y2]-s[x2][y1-1]-s[x1-1][y2]+s[x1-1][y1-1]);
}
return 0;
}
AcWing 797. 差分
#include
using namespace std;
int n,m;
const int N = 100005;
int a[N],b[N];
void insert(int l,int r,int c)
{
b[l]+=c;
b[r+1]-=c;
}
int main()
{
cin>>n>>m;
for(int i=1;i<=n;i++) cin>>a[i];
for(int i=1;i<=n;i++) insert(i,i,a[i]);
while(m--)
{
int l,r,c;
cin>>l>>r>>c;
insert(l,r,c);
}
for(int i=1;i<=n;i++)
b[i] += b[i-1];
for(int i=1;i<=n;i++)
cout<
AcWing 798. 差分矩阵
#include
using namespace std;
const int N = 1005;
int n, m, q;
int a[N][N],b[N][N];
void insert(int x1,int y1,int x2, int y2,int c)
{
b[x1][y1]+=c;
b[x2+1][y1]-=c;
b[x1][y2+1]-=c;
b[x2+1][y2+1]+=c;
}
//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
int main()
{
cin>>n>>m>>q;
for(int i=1;i<=n;i++)
for(int j=1;j<=m;j++)
{
cin>>a[i][j];
// 构建差分数组
// b[i][j]=a[i][j]-a[i-1][j]-a[i][j-1]+a[i-1][j-1];
}
// 构建差分数组
for(int i=1;i<=n;i++)
for(int j=1;j<=m;j++)
{
insert(i,j,i,j,a[i][j]);
}
while(q--)
{
int x1,y1,x2,y2,c;
cin>>x1>>y1>>x2>>y2>>c;
insert(x1,y1,x2,y2,c);
}
for(int i=1;i<=n;i++)
{
for(int j=1;j<=m;j++)
{
a[i][j] = b[i][j]+a[i-1][j]+a[i][j-1]-a[i-1][j-1];
cout<
冶炼金属
整除性质
#include
using namespace std;
//整除性质
// 已知A ,B V是所求 int(A/V)=B
// B<= A/V = V/A > 1/(B+1)
// A/B >= V > A/(B+1)
// Vmin = max(Vmin, int(A/(B+1))+1) Vmax = min(Vmax,A/B)
//当A/(B+1)是小数时,V不能为0,所以加一 A/B就算是小数也满足>=的性质
// A/Bmax = 1e9/1 A/bmin=1/1 => V->[1,1e9]
int n,a,b;
int v_min = 0,v_max = 1e9;
int main()
{
cin>>n;
for(int i=0;i>a>>b;
v_min = max(v_min,a/(b+1)+1);
v_max = min(v_max,a/b);
}
printf("%d %d",v_min,v_max);
return 0;
}
二分查找
//枚举能被最大整除和最小整除的数
#include
using namespace std;
int n,a,b;
int v_min = 0,v_max = 1e9;
// 二分查找 这里右边界是可以取等的 所以后面的要-1
int get(int a,int b)
{
int l = 1,r = 1e9+1;
while (l>1;
if (a/mid<=b) r=mid;// 转换之后 => a/b<=mid ->r=mid 没毛病
else l =mid+1;
}
return l;
}
int main()
{
cin>>n;
while(n--)
{
cin>>a>>b;
v_min = max(v_min,get(a,b));
v_max = min(v_max,get(a,b-1)-1);
}
cout<