zoukankan      html  css  js  c++  java
  • 蓝桥杯子总结

    <memory.h>或<string.h>
    
    void *memset(void *s, int ch, size_t n);
    
     
    
    #include <algorithm>
    
    sort(a,a+n)排序函数,从小到大,a为数组名字,n为元素个数
    
    sort(vector.begin(),vector.end())排序vector
    
    只要数据类型定义了小于操作符,即可用sort
    
    sort(a,a+n,compare)即可按照自定义顺序排列,compare为比较函数,返回值为bool
    
    lower_bound(a,a+n,x)二分查找,查找大于或等于x的第一个位置,只能查找vector<>数组,返回值为vector<>::iterator指针
    
        unique(vector1.begin(),vector1.end()),重排元素,使得所有值提前,返回值为重排后最后一个非重复值的后面的值的迭代器,即从返回值到vector1.end()是无意义的值,也是重复值的总数量
    
    reverse(vector1.begin(),vector1.end()),反转元素顺序
    
    next_permutation(p,p+n),求下一个全排列,枚举用
    
     
    
    #include <vector>   数组
    
    定义示例:vector<int> b(5);或者vector<int> a;
    
    赋值:b[0]=1;只有第一种定义可以这样赋值
    
    函数:
    
    int size(),获取大小
    
    void resize(int num),改变大小
    
    void push_back(int x),向尾部添加元素
    
    void pop_back(),删除最后一个元素
    
    void clear(),清空
    
    bool empty(),检查是否为空
    
    iterator insert(iterator x,y),向vector数组的x位置插入元素y,x可以为v.begin()+2
    
    iterator erase(iterator x),删除vector数组的x位置元素
    
    iterator begin(),返回头指针
    
    iterator end(),返回尾指针
    
    vector<>::iterator为一个可以指向其元素的指针
    
     
    
    #include <set>         集合,其中不含重复元素,且其中元素已从小到大排序,从1开始
    
    定义示例:set<int> a;
    
    函数:
    
    int size(),获取大小
    
    iterator find(x),若找到x,返回该键值迭代器的位置,否则,返回最后一个元素后面一个位置,即s.end()
    
    void clear(),清空
    
    bool empty(),检查是否为空
    
    iterator insert(y),向set集合插入元素y
    
    iterator erase(iterator x),删除set集合的值为x的元素,返回值为下一个位置的迭代器
    
    iterator begin(),返回头指针
    
    iterator end(),返回尾指针
    
    set<>::iterator为一个可以指向其元素的指针
    
     
    
    #include <map>       映射,索引
    
             定义示例:map<string,int> month_name;
    
    赋值:map[“July”]=7;
    
    函数:
    
    iterator find(y),寻找索引值为y的元素,返回指向其的指针
    
    iterator insert(map<string,int>(“July”,7)),向map映射插入元素(“July”,7)
    
    iterator erase(iterator x),删除map映射的迭代器x的元素
    
    map< string,int>::iterator l_it;;
    
       l_it=m.find(“July”);
    
       if(l_it==m.end())
    
            cout<<"we do not find July"<<endl;
    
       else  m.erase(l_it);  //delete July;
    
    iterator begin(),返回头指针
    
    iterator end(),返回尾指针
    
    map<>::iterator为一个可以指向其元素的指针
    
     
    
    #include <stack>
    
    定义示例:stack<int> s;
    
    void push(x),将值x压入栈
    
    void pop(),删除顶部元素
    
    top(),获得栈顶元素,但不删除
    
    bool empty(),检查是否为空
    
    int size(),获取大小
    
     
    
    #include <queue>
    
    定义示例:queue<int> q;
    
    void push(x),将值x入队
    
    void pop(),出队
    
    front(),获得队头元素,但不删除
    
    bool empty(),检查是否为空
    
    int size(),获取大小
    
     
    
    #include <string>
    
    string substr(int pos = 0,int n = npos) const;  //返回pos开始的n个字符组成的字符串
    
    void swap(string &s2);                                       //交换当前字符串与s2的值
    
    string &insert(int p0, const char *s);                //在p0位置插入字符串
    
    string &erase(int pos = 0, int n = npos);          //删除pos开始的n个字符,返回修改后的字符串
    
    int find(char c, int pos = 0) const;                     //从pos开始查找字符c在当前字符串的位置
    
    int find(const char *s,int pos = 0) const;         //从pos开始查找字符串s在当前串中的位置
    
     
    
    算法:
    
    快速排序:
    
    void quicksort(int *a,int l,int r){
             if(l>=r)
                      return;
             int temp=a[l];                                    //哨兵
             int i=l,j=r;
             while(i<j){
                      while(i<j){                                   //从右开始往左判断
                              if(a[j]>=temp){
                                       j--;
                              }
                              else{
                                      a[i++]=a[j];
                                      break;
                              }
                      }
                      while(i<j){                                   //从左开始往右判断
                              if(a[i]<=temp){
                                      i++;
                              }
                             else{
                                       a[j--]=a[i];
                                       break;
                              }
                      }
             }
             a[i]=temp;                                          //将哨兵放回中间位置
             quicksort(a,l,i-1);                               //左边排序
             quicksort(a,i+1,r);                             //右边排序
    }
    归并排序:
    void mergesort(int *a,int l,int r,int *b){
             if(l>=r)
                      return ;
             int mid=l+r;
             mid/=2;
             mergesort(a,l,mid,b);      //左边有序
             mergesort(a,mid+1,r,b);  //右边有序     
             int k=l,i=l,j=mid+1;                    //注意k的初值
             while(i<=mid&&j<=r){              //将i-mid和j-r两组有序序列,归并在一个有序序列中
                      if(a[i]<=a[j])
                             b[k++]=a[i++];
                      else
                              b[k++]=a[j++];
             }
             while(i<=mid)                            //将i-mid剩余的数放在最后
                      b[k++]=a[i++];
             while(j<=r)                                 //将j-r剩余的数放在最后
                      b[k++]=a[j++];
             for(k=l;k<=r;k++)                       //将b数组中的数据拷贝到原数组中
                      a[k]=b[k];
    }
    
    并查集:
    
    #define N 100
    
    int father[N];
    
    void init() {
        for(int i=0; i<N; i++)
          father[i] = i;
    }
    
    // 合并两个元素所在的集合
    
    void union(int x,int y) {
        x = getfather(x);
        y = getfather(y);
        if(x!= y)
           father[x]=y;
    }
    // 判断两个元素是否属于同一个集合
    
    bool same(int x,int y) {
    
        return getfather(x)==getfather(y);
    
    }
    
    // 获取根结点
    
    int getfather(int x) {
    
        while(x != father[x])
    
          x = father[x];
    
        return x;
    
    }
    // 获取根结点,是上边函数的改进,压缩了路径长度
    int getfather(int x) {
        if(x != father[x];
          father[x] = getfather(father[x]); // 路径压缩修改的是father数组
        return father[x];
    
    }
    二分查找:
    int erfen(int *a,int l,int r,int v){        //a为待查找数组,l为下界下标,r为上界下标,v为目标值
             int mid;
             while(l<=r){
                      mid=l+r;
                      mid/=2;
                      if(a[mid]==v)   return mid;
                      else if(a[mid]>v)      r=mid-1;
                      else  l=mid+1;
             }      
             return -1;
    }
    
    01背包动态规划:
    int f[5000];
    int v[201],w[201];
    int main(int argc, char** argv) {
             int n=0,m,i,j,mx=0;
             cin>>n>>m;
             for(i=1;i<=n;i++){
                      cin>>w[i]>>v[i];
             }
             for(i=1;i<=n;i++){
                      for(j=m;j>=w[i];j--){
                              f[j]=max(f[j],f[j-w[i]]+v[i]);
                              mx=max(mx,f[j]);
                      }
             }
             cout<<mx;
             return 0;
    }
     
    LIS最长上升子序列
    int LIS(int *a,int n){
             int *dp=new int[n];         //存储以i为尾的最长上升子序列长度
             int mx=0,m,i,j;
             dp[0]=1;                            //初值,第一个字符为1
             for(i=1;i<n;i++){
                      m=0;
                      for(j=0;j<i;j++){        //对当前i之前的所有元素的最长上升子序列做判断
                              if(dp[j]>m&&a[j]<a[i]){
                                       m=dp[j];
                              }
                      }
                      dp[i]=m+1;               //最大m值再加上1
                      mx=max(mx,dp[i]); //同时判断所有最长上升子序列长度的最大值
             }
             return mx;
    }
    
    LCS最长公共子序列
    动态规划法:
    void LCS(string str1,string str2)
    {
             int x_len = str1.length();
             int y_len = str2.length();
             int arr[50][50] = {{0,0}};
             int i = 0;
             int j = 0;
             //动态规划二维矩阵
             for(i = 1; i <= x_len; i++)
             {
                      for(j = 1; j <= y_len; j++)
                      {
                              if(str1[i - 1] == str2[j - 1])
                              {
                                       arr[i][j] = arr[i - 1][j - 1] + 1;
                             }
                              else
                              {
                                       if(arr[i][j - 1] >= arr[i - 1][j])
                                       {
                                                arr[i][j] = arr[i][j - 1];
                                       }
                                       else
                                      {
                                                arr[i][j] = arr[i -1][j];
                                       }
                              }
                      }
             }
            
             //打印最长公共子序列
    
             stack<char> s;
             for(i = x_len, j = y_len; i >= 1 && j >= 1;)
             {
                      if(str1[i - 1] == str2[j - 1])
                      {
                              s.push(str1[i - 1]);
                              //cout<<str1[i - 1]<<" ";
                              i--;  j--;
                      }
                      else
                      {
                              //  if(arr[i][j -1] >= arr[i - 1][j])//打印两种情况
                              if(arr[i][j -1] > arr[i - 1][j])
                              {
                                       j--;
                              }
                              else
                              {
                                       i--;
                              }
                      }
             }
             while(!s.empty()){
    
                      cout<<s.top();
    
                      s.pop();
    
             }
    
             cout << endl;
    
    }
    
    递归法:(只能求数量)
    
    int LCS(char* x,char *y){
    
             if(strlen(x)==0)                  return 0;
    
             if(strlen(y)==0)         return 0;
    
            
    
             if(*x==*y)         return LCS(x+1,y+1)+1;
    
             return max(LCS(x,y+1),LCS(x+1,y));
    
    }
    
     
    
    Dijkstra最短路径算法
    
    #define MAX 9999999
    
    #define NUM 6
    
    int edge[NUM][NUM];                     //存储两点间距离
    
    int dist[NUM];                                   //存储到每个点的最短距离
    
    int mark[NUM];                                 //标记是否已选
    
    //n:多少个点  start:起始点   
    
    void Dijkstra(int n,int start){
    
             int i,j,k=start;
    
             int min;
    
             for(i=0;i<n;i++){
    
                      mark[i]=0;
    
                      dist[i]=edge[start][i];
    
             }
    
             mark[start]=1;
    
             dist[start]=0;
    
             for(i=0;i<n;i++){
    
                      min=MAX;
    
                      for(j=0;j<n;j++){
    
                              if(!mark[j]&&dist[j]<min){
    
                                       min=dist[j];
    
                                       k=j;
    
                              }
    
                      }
    
                      mark[k]=1;
    
                      for(j=0;j<n;j++){
    
                              if(!mark[j]&&dist[j]>dist[k]+edge[k][j]){
    
                                       dist[j]=dist[k]+edge[k][j];
    
                              }
    
                      }
    
             }
    
    }
    
     
    
    Floyd
    
    #define MAX 9999999
    
    #define NUM 6
    
    int edge[NUM][NUM];
    
    int temp[NUM][NUM];
    
     
    
    void Floyd(int a[NUM][NUM],int b[NUM][NUM]){
    
             int i,j,k;
    
             for(k=0;k<NUM;k++){
    
                      for(i=0;i<NUM;i++){
    
                              for(j=0;j<NUM;j++){
    
                                       if(k==0)
    
                                                b[i][j]=a[i][j];
    
                                       else{
    
                                                b[i][j]=min(b[i][j],b[i][k]+b[k][j]);
    
                                       }
    
                              }
    
                      }
    
             }      
    
    }
    
     
    
    最小生成树(prim)最好选择下边Krusal算法
    
    #define MAX  100000
    
    #define VNUM  6                       
    
    int edge[NUM][NUM];
    
    int lowcost[NUM];             //记录Vnew中每个点到V中邻接点的最短边
    
    int addvnew[NUM];               //标记某点是否加入Vnew
    
    int adjecent[NUM];            //记录最小生成树的边,从adjecent[i]到i
    
     
    
    void prim(int start){
    
             int i,j,k;
    
             int v,min;
    
             int sum=0;
    
             for(i=0;i<NUM;i++){
    
                      addvnew[i]=0;
    
                      adjecent[i]=start;
    
                      lowcost[i]=edge[start][i];
    
             }
    
             addvnew[start]=1;
    
             for(i=0;i<NUM-1;i++){
    
                      min=MAX;
    
                      v=-1;
    
                      for(j=0;j<NUM;j++){
    
                              if(!addvnew[j]&&min>lowcost[j]){
    
                                       min=lowcost[j];
    
                                       v=j;
    
                              }
    
                      }
    
                      if(v!=-1){
    
                              addvnew[v]=1;
    
                              sum+=lowcost[v];
    
                              for(j=0;j<NUM;j++){
    
                                       if(!addvnew[j]&&lowcost[j]>edge[v][j]){
    
                                                lowcost[j]=edge[v][j];
    
                                                adjecent[j]=v;
    
                                       }
    
                              }
    
                      }
    
             }
    
    }
    
     
    
    Kruskal
    
    #define N 100
    
    Int w[N],p[i],r[i];     //w为权值数组,p为并查集数组,r为边权值排序数组,里边存储的是边的w对应的标号
    
     
    
    Int cmp(const int I,const int j){ return w[i]<w[j]; }
    
    Int find(int x){ return p[x]==x?x:find(p[x]); }
    
    Int Kruskal(){
    
             Int ans=0;
    
             For(int i=0;i<n;i++) p[i]=I;
    
             For(int i=0;i<n;i++) r[i]=I;
    
             Sort(r,r+m,cmp);//给边升序排列
    
             For(int i=0;i<n;i++){
    
                      Int e=r[i]; int x=find(u[e]); int y=find(v[e]);
    
                      If(x!=y) { ans+=w[e]; p[x]=y; }
    
             }
    
             return ans;
    
    }
    
     
    
    测试数据
    
    for(int i=0;i<VNUM;i++){
    
                      for(int j=0;j<VNUM;j++){
    
                              edge[i][j]=MAX;
    
                      }
    
             }
    
             edge[1][2]=5;
    
             edge[2][1]=5;
    
             edge[3][2]=3;
    
             edge[2][3]=3;
    
             edge[1][3]=4;
    
             edge[3][1]=4;
    
             edge[1][6]=7;
    
             edge[6][1]=7;
    
             edge[2][5]=6;
    
             edge[5][2]=6;
    
             edge[3][4]=2;
    
             edge[4][3]=2;
    
             edge[4][6]=3;
    
             edge[6][3]=3;
    
             edge[4][5]=1;
    
             edge[5][4]=1;
    
             edge[5][6]=4;
    
             edge[6][5]=4;
    
     
    
    可重集的全排列(递归)
    
    void print_permutation(int n,int P[],int A[],int cur)        //P按顺序存储待排列数,A同样大小的临时空间数组
    
    {
    
             int i,j;
    
             if(cur==n){
    
                      for(i=0;i<n;i++) printf("%d ",A[i]);                    //可输出可统计
    
                      printf("
    ");
    
             }
    
             else for(i=0;i<n;i++) if(!i||P[i]!=P[i-1]){
    
                      int c1=0,c2=0;
    
                      for(j=0;j<cur;j++) if(A[j]==P[i])c1++;
    
                      for(j=0;j<n;j++) if(P[i]==P[j])c2++;
    
                      if(c1<c2){
    
                              A[cur]=P[i];
    
                              print_permutation(n,P,A,cur+1);
    
                      }
    
             }
    
    }
    
    next_permutation(p,p+n),求下一个全排列
    
     
    
    二进制法求子集
    
    void print_submet(int n,int s){                 //打印一个子集
    
             for(int i=0;i<n;i++)                            
    
                      if(s&(1<<i)) printf("%d ",i);      //s=101时,代表子集{0,2}
    
             printf("
    ");
    
    }
    
    int main() {
    
             int n=7;                                                //代表集合{0,1,2,3,4,5,6},二进制表示
    
             for(int i=0;i<(1<<n);i++)                    //枚举所有子集
    
                      print_submet(n,i);
    
             return 0;
    
    }
    
     
    
    快速求幂
    
    int pow3(int x,int n){
    
             if(n==0)                                       //任何数的0次幂都是1
    
                      return 1;
    
             else{                                            //把尾部的0全部去除
    
                      while((n&1)==0){
    
                              n>>=1;
    
                              x*=x;
    
                      }
    
             }
    
             int res=x;                                    //后边的都不明白
    
             n>>=1;
    
             while(n!=0){
    
                      x*=x;
    
                      if((n&1)!=0)
    
                              res*=x;
    
                      n>>=1;
    
             }
    
             return res;
    
    }
    
     
    
    辗转相除法求最大公约数:
    
    int gcd(int a,int b){
    
             int temp;
    
             while(a%b!=0){
    
                      temp=a;
    
                      a=b;
    
                      b=temp%b;
    
             }
    
             return b;
    
    }
    
    辗转相除法最大公倍数:
    
    int lcm(int a,int b){
    
             int a1=a,b1=b,temp;
    
             while(a%b!=0){
    
                      temp=a;
    
                      a=b;
    
                      b=temp%b;
    
             }
    
             return a1/b*b1;
    
    }
    
    有重复元素的全排列:
    例如:有k个元素,其中第i个元素有ni个,求全排列个数。
    
    X=n!/(n1!*n2!......nk!)
    
     
    
    可重复选择的组合:
    
    有N个不同元素,每个元素可以选多次,一共选k个元素,有多少种选法?
    
    C(n+k-1,k)

    蓝桥总结

  • 相关阅读:
    Kafka 生产者 自定义分区策略
    同步互斥
    poj 1562 Oil Deposits(dfs)
    poj 2386 Lake Counting(dfs)
    poj 1915 KnightMoves(bfs)
    poj 1664 放苹果(dfs)
    poj 1543 Perfect Cubes (暴搜)
    poj 1166 The Clocks (暴搜)
    poj 3126 Prime Path(bfs)
    处理机调度
  • 原文地址:https://www.cnblogs.com/zuimeiyujianni/p/8633016.html
Copyright © 2011-2022 走看看