算法备赛模板(临时)(二)

简介: 算法备赛模板(临时)

杨辉三角

普通法

#include<bits/stdc++.h>
using namespace std;
int n;
int a[100][100];//存储杨辉三角每一行的内容
int main(){
  cin>>n;
  for(int i=1;i<=n;i++){//控制行
    for(int j=1;j<=i;j++){
      if(i==j||j==1) a[i][j]=1;//根据观察得出的
      else a[i][j]=a[i-1][j]+a[i-1][j-1]; //根据观察易得
    }
  }
  for(int i=1;i<=n;i++){
    for(int j=1;j<=i;j++){
      cout<<a[i][j]<<" ";
    }
    cout<<"\n";
  }
  return 0;
}

搜索

全排列

#include<bits/stdc++.h>
using namespace std;
int n;
int a[10];
bool b[10];
int dfs(int x){
    if(x==n){
        for(int i=0;i<n;i++) cout<<a[i]<<" ";
        cout<<"\n";
        return 0;
    }
    for(int i=1;i<=n;i++){
        if(!b[i]){
            a[x]=i;
            b[i]=true;
            dfs(x+1);
            b[i]=false;
        }
    }
}
int main(){
    cin>>n;
    dfs(0);
    return 0;
}

组合

#include<bits/stdc++.h>
using namespace std;
int a[10],b[10];
int n;
void dfs(int x,int st){
    if(x>=3){
        for(int i=0;i<3;i++) cout<<a[i];
        cout<<"\n";
        return ;
    }
    for(int i=st;i<=n;i++){
        if(!b[i]){
            a[x]=i;
            b[i]=true;
            dfs(x+1,st+1);
            b[i]=false;
        }
    }
}
int main(){
    cin>>n;
    dfs(0,1);
    return 0;
}

迷宫

#include<bits/stdc++.h>
using namespace std;
int n,m;
typedef pair<int,int> PII; //用来存点,用pair方便点点
const int N=110; //数据范围
int g[N][N],d[N][N];// g数组装整个图,  d数组表示某点到原点的距离
int bfs(){
    queue<PII> q;
    q.push({0,0});//首先起点入队
    memset(d,-1,sizeof d);//将最开始的所有点到起点的距离都设置为-1
    d[0][0]=0;//起点到起点的距离设置为0,
    int dx[4]={0,1,0,-1},dy[4]={1,0,-1,0}; /*方向数组,随便向那个方向扩展都得行,
    我的是上(x不变,y会加1)右(x会加1,y不变)下(x不变,y会减1)左(x会减1,y不变)*/
    while(!q.empty()){
        auto t = q.front();//取出队首元素
        q.pop();//队首出队
        for(int i=0;i<4;i++){//向4个方向扩展
            // x,y 为扩展后的, t装的是拓展前的坐标
            int x=t.first+dx[i];
            int y=t.second+dy[i];
            //满足边界条件,拓展的点的位置没有障碍,在之前没有被访问过(距离为-1就表示没访问过)
            if(x>=0&&x<n&&y>=0&&y<m&&g[x][y]==0&&d[x][y]==-1){
                d[x][y]=d[t.first][t.second]+1;//更新距离
                q.push({x,y});//将成功扩展的点入队
            }
        }
    }
    return d[n-1][m-1];//最终 d[n-1][m-1] 就是右下角到左上角的需要移动的最短距离
}
int main(){
    cin>>n>>m;
    //读入图的信息
    for(int i=0;i<n;i++)
        for(int j=0;j<m;j++)
            cin>>g[i][j];
    cout<<bfs()<<"\n";//输出结果
}

并查集

#include<bits/stdc++.h>
using namespace std;
// const int n=1000010;
int m,n;
int p[1000010];//存储节点的父亲
int findX(int x){//采用了路径压缩
    if(x!=p[x]) p[x]=findX(p[x]);
    return p[x];
}
int main(){
//    cin.tie(0);
//    ios::sync_with_stdio(false);
    cin>>n>>m;
    for(int i=1;i<=n;i++) p[i]=i;
    while(m--){
        string x;
        int a,b;
        cin>>x>>a>>b;
        if(x=="M") p[findX(a)] = findX(b);
        else{
            if(findX(a)==findX(b)) cout<<"Yes\n";
            else cout<<"No\n";
        }
    }
    return 0;
}

spfa求最短路

#include<bits/stdc++.h>
using namespace std;
#define maxn 1000010
int n,m;
//dist表示某点到起点的距离  
//st表示某个点是否加入队列 true表示没加入,反之则加入 
int dist[maxn],st[maxn];  
// h:头结点  w:权重  e:边  ne:下一个点   idx就表示节点 
int h[maxn],w[maxn],e[maxn],ne[maxn],idx;
void add(int a,int b,int c){//邻接表  模板,背到就可以   
  e[idx]=b,w[idx]=c,ne[idx]=h[a],h[a]=idx++;
}
int spfa(){
  memset(dist,0x3f,sizeof(dist));//将初始距离设为很大的数 
  queue<int> q;
  dist[1]=0;// 初始化第一个点到第一个点的距离为 0 ,方便后面的计算 
  q.push(1);// 先将第一个点加入队列 
  st[1]=true;//第一个点加入了队列,所以 st[1] = true 
  while(!q.empty()){//广搜的模板 
    int t = q.front();//取出第一个节点 
    q.pop();//取出了后,就要出队列 
    st[t]=false;//取出后,没在队列了,设置为 false 
    for(int i=h[t];i!=-1;i=ne[i]){//更新t的出边 
      int j = e[i];//获得和t相连的点
      if(dist[j]>dist[t]+w[i]){//如果可以距离变得更短,则更新距离
        dist[j]=dist[t]+w[i];
        if(!st[j]){//如果没在队列中,可以入队 
          q.push(j);
          st[j]=true;//入队了,设置为false 
        } 
      }
    }
  }
  return dist[n]==0x3f3f3f3f?-2:dist[n];
}
int main(){
  cin>>n>>m;
  memset(h,-1,sizeof(h));//这一步不能忘记 
  while(m--){
    int x,y,z;  cin>>x>>y>>z;
    add(x,y,z);
  }
  int ans=spfa();
  if(ans!=-2) cout<<dist[n];
  else cout<<"impossible"; 
  return 0;
}

参考了博客:https://www.acwing.com/solution/content/105508/

动态规划

01背包

https://www.acwing.com/problem/content/2/

#include<bits/stdc++.h>
#define ll long long 
using namespace std; 
#define maxn 10010
int N,V;// N件物品,V为背包体积 
int v[maxn],w[maxn];// v数组装物品的体积 , w数组装物品的价值 
int dp[10010];
int main(){
  cin>>N>>V;
  for(int i=1;i<=N;i++) cin>>v[i]>>w[i];
  for(int i=1;i<=N;i++){
    for(int j=V;j>=v[i];j--){//dp[j]为 容量为j的背包所背的最大价值 
      dp[j]=max(dp[j],dp[j-v[i]]+w[i]); 
    }
  } 
  cout<<dp[V]; 
  return 0; 
}

完全背包

https://www.acwing.com/problem/content/description/3/

#include<bits/stdc++.h>
#define ll long long 
using namespace std; 
#define maxn 10010
int N,V;// N件物品,V为背包体积 
int v[maxn],w[maxn];// v数组装物品的体积 , w数组装物品的价值 
int dp[10010];
int main(){
  cin>>N>>V;
  for(int i=1;i<=N;i++) cin>>v[i]>>w[i];
  for(int i=1;i<=N;i++){
    for(int j=v[i];j<=V;j++){//dp[j]为 容量为j的背包所背的最大价值 
      dp[j]=max(dp[j],dp[j-v[i]]+w[i]); 
    }
  } 
  cout<<dp[V]; 
  return 0; 
}

多重背包

https://www.acwing.com/problem/content/description/4/

强制拆分成 01 背包来做

#include<bits/stdc++.h>
#define ll long long 
using namespace std; 
#define maxn 100010
int N,V;// N件物品,V为背包体积 
int v[maxn],w[maxn];// v数组装物品的体积 , w数组装物品的价值 
int dp[10010];
int len=0;//用来记录 v 与 w 数组的长度 
int main(){
  cin>>N>>V;
  for(int i=1;i<=N;i++){
    int vi,wi,s;  cin>>vi>>wi>>s;
    while(s--){//拆成 01 背包来做
      v[++len]=vi;
      w[len]=wi; 
    } 
  } 
  for(int i=1;i<=len;i++){//这里就是有 len 个物品了
    for(int j=V;j>=v[i];j--){//dp[j]为 容量为j的背包所背的最大价值 
      dp[j]=max(dp[j],dp[j-v[i]]+w[i]); 
    }
  } 
  cout<<dp[V]; 
  return 0; 
}

分组背包

#include<bits/stdc++.h>
#define ll long long 
using namespace std; 
#define maxn 150
int N,V;// N件物品,V为背包体积 
int v[maxn][maxn],w[maxn][maxn],s[maxn];// v数组装物品的体积 ,w数组装物品的价值 ,s数组表示第每组物品的个数 
int dp[10010];
int len=0;//用来记录 v 与 w 数组的长度 
int main(){
  cin>>N>>V;
  for(int i=1;i<=N;i++){
    cin>>s[i];
    for(int j=0;j<s[i];j++){
      cin>>v[i][j]>>w[i][j];
    }
  } 
  for(int i=1;i<=N;i++){// n组 
    for(int j=V;j>=0;j--){
      for(int k=0;k<s[i];k++){
        if(v[i][k]<=j) dp[j]=max(dp[j],dp[j-v[i][k]]+w[i][k]);
      }
    }
  } 
  cout<<dp[V]; 
  return 0; 
}
相关文章
|
4月前
|
算法
Hierholzer算法dfs找欧拉回路模板
Hierholzer算法dfs找欧拉回路模板
38 0
|
8月前
|
存储 算法 决策智能
(万字,细细阅读)竞赛算法入门必经算法模型(附带题目链接和模板)(下)
(万字,细细阅读)竞赛算法入门必经算法模型(附带题目链接和模板)(下)
49 0
|
8月前
|
算法 C++ 容器
(万字,细细阅读)竞赛算法入门必经算法模型(附带题目链接和模板)(上)
(万字,细细阅读)竞赛算法入门必经算法模型(附带题目链接和模板)(上)
28 0
|
7月前
|
算法 C++ 索引
函数模板和类模板 知识点总结 C++程序设计与算法笔记总结(七) 北京大学 郭炜(下)
函数模板和类模板 知识点总结 C++程序设计与算法笔记总结(七) 北京大学 郭炜(下)
26 0
|
3月前
|
存储 算法 搜索推荐
C++模板与STL【常用算法】
C++模板与STL【常用算法】
|
8月前
|
算法 计算机视觉
基于方向编码的模板匹配算法matlab仿真
基于方向编码的模板匹配算法matlab仿真
|
7月前
|
算法 编译器 C++
函数模板和类模板 知识点总结 C++程序设计与算法笔记总结(七) 北京大学 郭炜(上)
函数模板和类模板 知识点总结 C++程序设计与算法笔记总结(七) 北京大学 郭炜(上)
31 1
|
8月前
P4057 [Code+#1]晨跑(数学分析,辗转相除法模板(欧几里得算法))
P4057 [Code+#1]晨跑(数学分析,辗转相除法模板(欧几里得算法))
24 0
|
8月前
|
算法
算法备赛模板(临时)(一)
算法备赛模板(临时)
|
1天前
|
存储 算法 数据可视化
基于harris角点和RANSAC算法的图像拼接matlab仿真
本文介绍了使用MATLAB2022a进行图像拼接的流程,涉及Harris角点检测和RANSAC算法。Harris角点检测寻找图像中局部曲率变化显著的点,RANSAC则用于排除噪声和异常点,找到最佳匹配。核心程序包括自定义的Harris角点计算函数,RANSAC参数设置,以及匹配点的可视化和仿射变换矩阵计算,最终生成全景图像。