栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > C/C++/C#

CSP-J 模板(部分)

C/C++/C# 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

CSP-J 模板(部分)

整理:Littlefools(Zbt 小蒟蒻)

算法篇: 1. 搜索 DFS(深搜)
void dfs(int depth){ //输入的是深度
if(depth==n){ //深度超出范围,说明找到一个解
//找到了一个解,对这个解进行处理包括但不限于解的数量,更新搜索最优值
return;
}
//扩展节点,比如
for(int i=1;i<=n;i++){ //处理节点
dfs(depth+1);
//部分问题需要恢复状态,如 N 皇后。
}
}
BFS(广搜)
queue q;//存储状态
void bfs(){
q.push(...)//初始状态入队
while(!q.empty()){
int s=q.front();q.pop();//获取状态
//处理结点
if(s 达到某种条件){
//输出或做些什么
return;
}
//扩展状态
for(int i=1;i<=n;i++){
int s;
q.push(s);
}
}
//运行到这里,就是搜不着,无解。
}

加入可行性剪枝进行优化。如果不优化不一定能 AC。
写搜索时应该先从朴素算法入手,逐步优化,以降低复杂度、减少不必要的失误。
如果不能套用,先写暴搜,命名为#0 版本。
更多的调试技巧参见老刘书上 P113 页。迭代加深搜索参见 P112。

2. 排序 1.STL
bool mycmp(type_A,type_B){return a 
2.桶排序 
int bucket[1001],i,j,x,n;
memset(bucket,0,sizeof(bucket));
cin>>n;//输入一个数 n,表示接下来有 n 个数
for(i=1;i<=n;i++){
cin>>x; //把每一个数读到变量 x 中
bucket[x]++; //进行计数,对编号为 t 的桶放一个小旗子
}
for(i=1000;i>=0;i--){ //这里枚举的是数的范围。
for(j=1;j<=bucket[i];j++){ //出现了几次就将桶的编号打印几次
cout< 
3. 快速排序(分治,重在理解) 
void quicksort(int start,int end){
int low=start,high=end,check=a[(start+end)/2];
//划分,把比 check 小的数放它的左边,大的放右边。
while(low<=high){
while(a[low]check && low<=high) high--;//在右端找到第一个比 check 小的数。
if(low<=high){
swap(a[low],a[high]);
low++;high--;
}
}
if(high>start) quicksort(start,high);
if(low>n;
for(int i=1;i<=n;i++) cin>>a[i];
quicksort(1,n);
for(int i=1;i<=n;i++) cout< 

更多的不常用排序方法,参见老刘书 P17。

3. 分治 1.快速幂

给你三个整数 ,求(b^p)%k 的值。

long long b,p,k,ans=1;
cin>>b>>p>>k;
while(p>0){
if(p%2!=0) ans=ans*b%k;//如果 p 为单数,乘到 ans 里面去,然后取模
b=b*b%k;//每次运算都取模
p=p/2;
}
ans=ans%k;//在 p = 0 时有取模
cout< 
2.二分查找 
int find(int x){
int left=1,right=n,mid=(left+right)/2;//左边界,右边界,二分中间点
while(left+1x) right=mid;//如果在左半部分
}
if(a[left]==x) return left;
if(a[left]==x) return right;
return -1;//没有找到。
}
3.二分答案

这个算法比较难以理解,推荐博客 。
例如:求最小值

int binary(){
int l=0, r=n, mid;
while(l < r){
mid = (l + r) /2;
if(check(mid)) r = mid; //大多数题只要改改 check()即可
else l = mid + 1;
}
return l;
}

二分答案与二分查找类似,即对有着单调性的答案进行二分, 大多数情况下用于求解满足
某种条件下的最大(小)值。

4. 数学 ①.组合数学基础

加法原理:在第 n 类办法中有풎풏种不同的方法,那么完成这件事有 N=m1…+ 풎풏种方法。(分类)
乘法原理:做一件事完成有 n 个步骤,做第 n 种有풎풏种不同方法。有 N=m1*…풎풏 种方法。(分步)
排列:从 n 个不同元素中,任取 m 个元素,按照一定的顺序排成一列。(元素有序)
当 n = m n=m n=m时为全排列,方案数为 n ! n! n!
组合:从 n 个不同元素中,任选 m 个元素并成一组,叫从 n 个不同元素中取出 m 个元素的一个组合。

注意代码要先乘后除,避免出现小数。for(int i=1;i<=n;i++) c[i]=c[i-1]*(n-i+1)
应用:
(1)隔板法(2)插空法(3)捆绑法(4)圆排列(5)错排(6)容斥原理(重要)
具体用法请自己查询,由于编者手头有一本《进阶指南》,上面有全的。在这里不过多阐述。

②数位相关

1.统计数字位数。

int cont(int n){ //统计 n 的位数
int sum=0;
while(n>0){
sum++;
n=n/10;
}
return sum;
}

2.统计 n 的数字和

int sum(int n){ //统计 n 的数字和
int sum=0;
while(n>0){
sum=sum+n%10;
n=n/10;
}
return sum;
}

3.计算 n 的逆序数

int rev(int n){ //计算 n 的逆序数
int sum=0;
while(n>0){
sum=sum*10+n%10;
n=n/10;
}
return sum;
}

4.判断 n 是否为回文数

bool pal(int n){ //判断是否是回文数
int sum=0,m=n;
while(n>0){
sum=sum*10+n%10;
n=n/10;
}
return sum==m;
}

5.判断 n 在 b 进制下是不是回文数

bool pal(int n,int b){
int sum=0,m=n;
while(n>0){
sum=sum*b+n%b;
n=n/b;
}
return sum==m;
}

③进制相关
十进制转二进制:

//十进制转二进制->将数字%2,余数存在数组里然后将这些数字除 2,重复,直到数字大于 0
for(i=0;n>0;i++){
a[i]=n%2;
n=n/2;
}
for(i=i-1;i>=0;i--) cout< 

二进制转十进制,则是反过来:

int n,ans=0,m,k=0;
cin>>n;
while(n!=0){
m=n%10;
n=n/10;
ans=ans+m*pow(2,k++);
}
cout<
转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/302579.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号