计算机CS夏令营刷题模板(实时更新)

参照acwing给出知识点,做的是对应洛谷的模板题,
该帖暂时搁置了,因为博主准备刷一下3月底的csp,去刷板子题去了,4月会回来的!

待问

  1. 是否可以使用万能头文件
  2. 上机环境:可不可以使用devc++,学习vscode调试

一、基础算法

  1. 排序
    题目
    快排
#include<bits/stdc++.h>
using namespace std;
int n;

void quick_sort(int a[],int l,int r)
{
    if(l>=r)return;
    int i=l-1,j=r+1,mid=a[(l+r)>>1];
    while(i<j)
    {
        do i++;while(a[i]<mid);
        do j--;while(a[j]>mid);
        if(i<j)swap(a[i],a[j]);
    }
    quick_sort(a,l,j);//不能为j-1
    quick_sort(a,j+1,r);
}

int main()
{
    freopen("in.txt","r",stdin);
    int a[100005];
    scanf("%d",&n);
    for(int i=1;i<=n;i++)
        scanf("%d",&a[i]);
    quick_sort(a,1,n);

    for(int i=1;i<=n;i++)
    printf("%d ",a[i]);

    return 0;
}

归并排序

#include<bits/stdc++.h>
using namespace std;

int n,a[100005],tmp[100005];
void merge_sort(int l,int r)
{
	if (l>=r)return ;
	
	int mid=l+r>>1;
	merge_sort(l,mid);
	merge_sort(mid+1,r);
	
	int k=l,i=l,j=mid+1;
	while(i<=mid&&j<=r)
	{
		if(a[i]<a[j])tmp[k++]=a[i++];
		else tmp[k++]=a[j++];
	}
	
	while(i<=mid)tmp[k++]=a[i++];
	while(j<=r)  tmp[k++]=a[j++];
	
	for(i=l;i<=r;i++)a[i]=tmp[i];
}

int main()
{
	freopen("in.txt","r",stdin);
	scanf("%d",&n);
	for(int i=1;i<=n;i++)
		scanf("%d",&a[i]);
		
	merge_sort(1,n);
	
	for(int i=1;i<=n;i++)
		printf("%d ",a[i]); 
	return 0;
}
  1. 二分
    整数二分,跳石头
    贪心+二分答案
#include<bits/stdc++.h>
using namespace std;
int len,n,m,a[500005];

bool test(int x)
{
	int dis=0,cnt=0,alast=0;
	for(int i=1;i<=n;i++)
	{
		if(a[i]-alast<x)cnt++;//第i块石头需要移走;
		else alast=a[i]; 
		if(cnt>m)return 0;
	}
	return 1;
}

int main()
{
	freopen("in.txt","r",stdin);
	scanf("%d %d %d",&len,&n,&m);
	for(int i=1;i<=n;i++)
		scanf("%d",&a[i]);	
	n++;
	a[n]=len;
	
	int l=1,r=len,mid;
	while(l<=r)
	{
		mid=l+r>>1;
		if(test(mid))l=mid+1;
		else r=mid-1;
	}
	
	printf("%d",l-1);
	return 0;
}

浮点数二分
一元三次方程noip2001的题
法1:求导得 3 a x 2 + 2 b x + c = 0 3ax^2+2bx+c=0 3ax2+2bx+c=0,可得两个拐点y1,y2,然后可以直接三分区间

#include<bits/stdc++.h>
using namespace std;
double a,b,c,d;

double f(double x)
{
	return a*x*x*x+b*x*x+c*x+d;
}

double get_ans(double l,double r)
{
	double mid=(l+r)/2;
	while(r-l>1e-3)
	{
		mid=(l+r)/2;
		if(f(l)*f(mid)<0)r=mid;
		else l=mid;
	}
	return mid;
}

int main()
{
	freopen("in.txt","r",stdin);
	//一定有三个解!!! 
	scanf("%lf %lf %lf %lf",&a,&b,&c,&d);
	double x1,x2,x3,y1,y2,l=-100,r=100;
	x1=(-2*b+sqrt(4*b*b-4*3*a*c))/(6*a);
	x2=(-2*b-sqrt(4*b*b-4*3*a*c))/(6*a);
	y1=min(x1,x2);
	y2=max(x1,x2);
	x1=get_ans(l,y1);
	x2=get_ans(y1,y2);
	x3=get_ans(y2,r);
	printf("%.2lf %.2lf %.2lf",x1,x2,x3); 
	return 0;
}

法2枚举:<性能更优>
根据题目条件(根与根之差的绝对值 ≥1)枚举200个区间即可

#include<bits/stdc++.h>
using namespace std;
double a,b,c,d;

void vivi()
{
freopen("input.txt","r",stdin);
freopen("output.txt","w",stdout);	
}

void readata()
{
scanf("%lf%lf%lf%lf",&a,&b,&c,&d);	
}

double f(double x)
{
	return a*x*x*x+b*x*x+c*x+d;
}
double finf(double l,double r)
{
	double m;
	while(r-l>=1e-3)
	{
		m=(l+r)/2;	
		if(f(l)*f(m)<0)r=m;
		else if(f(l)==0)	return l;
		else l=m;
	}
	return l;
}
void work()
{
	for(double i=-100;i<=100;i++)
	{
	double j;
	j=i+1;
		if(f(i)==0){printf("%.2lf",i);cout<<" ";}
		else if(f(i)*f(j)<0){printf("%.2lf",finf(i,j));;cout<<" ";}
	}
}



int main()
{
	//vivi();
	readata();
	work();
	return 0;
} 
  1. 高精度
  2. 前缀和与差分
  3. 双指针算法
  4. 位运算
  5. 离散化
  6. 区间合并

二、数据结构

  1. 链表与邻接表:树与图的存储
  2. 栈与队列:单调队列、单调栈.
  3. kmp
  4. Trie
  5. 并查集
    关押罪犯
    并查集+重载结构体运算符
#include<bits/stdc++.h>
using namespace std;

const int maxn=20005,maxm=100005;
int n,m,fa[maxn<<1];
struct edge{
	int x,y,val;
	bool operator<(const edge &aa)const{
		return val>aa.val;
	}
}e[maxm];

int find(int x){
	return fa[x]==x?x:fa[x]=find(fa[x]);
}

int main()
{
	freopen("in.txt","r",stdin);
	int l=0,r=1,mid;
	scanf("%d %d",&n,&m);
	for(int i=1;i<=m;i++)
	{	
		scanf("%d %d %d",&e[i].x,&e[i].y,&e[i].val);
		if(e[i].val>r)r=e[i].val;
	}
	
	sort(e+1,e+m+1);

	for(int i=1;i<=n+n;i++)fa[i]=i;
	for(int i=1;i<=m;i++)
	{
		int x=e[i].x,y=e[i].y;
		if(find(fa[x])==find(fa[y])){
			printf("%d ",e[i].val);
			return 0; 
		}
		fa[find(x)]=find(y+n);
		fa[find(y)]=find(x+n);
	}
	printf("0");
	return 0;
}
  1. Hash表

三、搜索与图论

  1. DFS与BFS
  2. 树与图的遍历:拓扑排序·最短路
  3. 最小生成树
  4. 二分图:染色法、匈牙利算法

四、 数学知识

  1. 质数
  2. 约数
  3. 欧拉函数
  4. 快速幂
  5. 扩展欧几里得算法
  6. 中国剩余定理
  7. 高斯消元
  8. 组合计数
  9. 容斥原理
  10. 简单博弈论

五、 动态规划

  1. 背包问题
  2. 线性DP
  3. 区间DP
  4. 计数类DP
  5. 数位统计DP
  6. 状态压缩DP
  7. 树形DP
  8. 记忆化搜索
  9. 贪心
  • 8
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值