基础算法——c(少量c++)模板

本文介绍了几种基础但重要的算法,包括快速排序和归并排序的详细步骤,以及二分查找的不同变体。还探讨了高精度加法的实现和一维、二维前缀和的概念。此外,提到了位运算在求解特定问题中的应用,如获取数字的某位和最后一位1。最后,展示了如何运用双指针解决区间合并问题。
摘要由CSDN通过智能技术生成

快速排序

void quick_sort(int q[],int l,int r)
{
	if(l>=r)return;
	int i=l-1,j=r+1,x=q[l+r>>1];
	while(i<j){
		do i++;while(q[i]<x);
		do j--;while(q[j]>x);
		if(i<j)swap(q[i],q[j]);
	}
	quick_sort(q,l,j),quick_sort(q,j+1,r);
}

归并排序

void merge_sort(int q[],int l,int r){
	if(l>=r)return;
	int mid=l+r>>1;
	merge_sort(q,l,mid);
	merge_sort(q,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];
}

整数二分算法

bool check(int x){}

//区间[l,r]被划分成[l,mid]和[mid+1,r]时使用:
int bsearch_1(int l,int r){
	while(l<r){
		int mid=l+r>>1;
		if(check(mid)) r=mid; //check()判断mid是否满足性质
		else l=mid+1;
	}
	return l;
}

//区间[l,r]被划分成[l,mid-1]和[mid,r]时使用:
int bsearch_2(int l,int r){
	while(l<r){
		int mid=l+r+1>>1;
		if(check(mid))l=mid;
		else r=mid-1;
	}
	return l;
}

浮点数二分

bool check(double x){}

double bsearch_3(double l,double r){
	double eps=1e-6;
	while(r-l>eps){
		double mid=(l+r)/2;
		if(check(mid))r=mid;
		else l=mid;
	}
	return l;
}

高精度加法

#include<stdio.h>
#include<string.h>
#include<math.h>

#define N 100010

char a[N];
char b[N];
int A[N];
int B[N];

int main(){
	scanf("%s %s",a,b);
	int lenA=strlen(a);
	int lenB=strlen(b);
	int j=0;
	int i=0;
	for(i=lenA-1,j=0;i>=0;i--,j++)A[j]=a[i]-'0';
	for(i=lenB-1,j=0;i>=0;i--,j++)B[j]=b[i]-'0';
	
	int C[N];
	int t=0;
	for(i=0;i<lenA||i<lenB;i++){
		if(i<lenA)t += A[i];
		if(i<lenB)t += B[i];
		C[i]=t%10;
		t/=10;
	}

	if(t!=0){
		C[i]=t;
		for(j=i;j>=0;j--)printf("%d",C[j]);
	}
	for(j=i-1;j>=0;j--)printf("%d",C[j]);
	return 0;
}

一维前缀和

S[i]=a[1]+a[2]+...+a[i];
a[l]+...+a[r]=S[r]-S[l-1];

二维前缀和

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

一维差分

给区间[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

位运算

求n的第k位数字:n>>k&1
返回n的最后一位1lowbit(n)=n&-n

双指针算法

for(int i=0,j=0;i<n;i++){
	while(j<i&&check(i,j))j++;
	//具体问题逻辑
}
常见问题分类:
	(1)对于一个序列,用两个指针维护一段区间
	(2)对于两个序列,维护某种次序,比如归并排序中合并两个有序序列的操作

区间合并

#include<stdio.h>

#define N 100010

int n;

struct interval{
	int l;
	int r;
};

struct interval in[N];
struct interval res[N];

void quick_sort(int l,int r){
	if(l>=r)return;
	
	int i=l-1,j=r+1,x=in[(l+r)/2].l;
	while(i<j){
		do i++;while(in[i].l<x);
		do j--;while(in[j].l>x);
		if(i<j){
			struct interval temp=in[i];
			in[i]=in[j];
			in[j]=temp;
		}
	}
	quick_sort(l,j),quick_sort(j+1,r);
}

void merge(){
	quick_sort(0,n-1);
	int st=-2e9,ed=-2e9;
	int i;
	int k=1;
	for(i=0;i<n;i++){
		if(ed<in[i].l){
			if(st!=-2e9){
				res[k].l=st;
				res[k++].r=ed;
			}
			st=in[i].l,ed=in[i].r;
		}
		else{
			if(ed<in[i].r)ed=in[i].r;
		}
	}
	printf("%d",k);
}

int main(){
	scanf("%d",&n);
	int i;
	for(i=0;i<n;i++){
		scanf("%d%d",&in[i].l,&in[i].r);
	}
	merge();
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值