• 各类算法模板


    gcd

    int gcd(int a,int b)///辗转相除法求最大公约数
    {
    
        int t = a;
        while(a%b)
        {
            a=b;
            b=t%b;
            t=a;
        }
        return b;
    }
    View Code

    或者

    int gcd(int a, int b)
    {
        return b == 0 ? a : gcd(b, a%b);
    }
    View Code

    exgcd

    扩展欧几里得算法

    给予二整数 a 与 b, 必存在有整数 x 与 y 使得ax + by = gcd(a,b)

    int exgcd(int a2,int  b2,int &x,int &y)
    {
        if(b2==0)
        {
            x=1;y=0;
            return a2;
        }
    
        int ans = exgcd(b2,a2%b2,x,y);
        double temp=x;
        x=y;
        y=temp-a2/b2*y;
        return ans;       ///返回的还是最大公约数 但是我们就方便求x和y
    
    }
    View Code
    int tocal(int a3,int b3)
    {
        int x0,y0;
        int gcd = exgcd(a3,b3,x0,y0);
        if(1%gcd!=0) return -1; ///gcd得等于1  ...
        x0*=1/gcd;
        b3=abs(b3);
        int ans = x0%b3;
        if (ans<=0) ans+=b3;
        return ans;
    
    
    }
    View Code

    lcm:

    int lcm(int a,int b)
    {
        return a * b / gcd(a, b);
    }
    那么求什么最大公约数最小公倍数 乘法逆元全都解决了

    当然我当时也费尽心思研究了一番 为了RSA加密算法

    01背包:

    有一个容量为V的背包,现在有n件物品,每件物品所占空间为w[i],价值为v[i],求 背包中所装物品价值最大值

    注意每个物品就一件

    for(i=1;i<=n;i++)
        for(j=V;j>=w[i];j--)
            f[j]=max(f[j],f[j-w[i]]+v[i]);

    完全背包

    完全背包是有n种物品,每种物品可以取无线多件,每件物品所占空间为w[i],价值为v[i]

    for(i=1;i<=n;i++)
        for(j=w[i];j<=V;j++)
            f[j]=max(f[j],f[j-w[i]]+v[i]);

    高精度加法:

    #include<bits/stdc++.h>
    using namespace std;
    string a,b;
    string Precise_add(string a,string b){
        int lena=a.length();
        int lenb=b.length();
        int aa,bb,sum,flag=0;
        while(lena>0){
            aa=a[lena-1]-'0';
            if(lenb>0)
                bb=b[lenb-1]-'0';
            else
                bb=0;
            sum=aa+bb+flag;
            if(sum>=10){
                a[lena-1]='0'+sum%10;
                flag=1;
            } 
            else{
                a[lena-1]='0'+sum;
                flag=0;
            }
            lena--;
            lenb--;
        } 
        if(flag==1)
            a="1"+a;
        return a;
    }
    int main(){
        cin>>a>>b;
        if(a.size()<b.size())
            swap(a,b);
        cout<<Precise_add(a,b)<<endl;
        return 0;
    }
    View Code

    快速幂算法:

    #include<bits/stdc++.h>
    #define ll long long
    using namespace std;
    ll Q(ll n,ll m){
        ll res=1;
        while(m){
            if(1&m)
                res=res*n;
            n=n*n;
            m>>=1;
        }
        return res;
    }
    int main(){
        
        cout<<Q(5,12)<<endl;
        return 0;
    }
    View Code

    DFS:

    #include<bits/stdc++.h>
    using namespace std;
    int a[105][105],b[105][105];
    int n,m,startx,starty,endx,endy,ans=999999999;
    int next[4][2]={{1,0},{0,1},{-1,0},{0,-1}};
    void dfs(int x,int y,int step){
        if(x==endx&&y==endy){
            ans=min(ans,step);
            return;
        }
        for(int i=0;i<4;i++){
            int xx=x+next[i][0];
            int yy=y+next[i][1];
            if(xx<1||xx>n||yy<1||yy>m) continue;
            if(a[xx][yy]==0&&b[xx][yy]==0){
                b[xx][yy]=1;
                dfs(xx,yy,step+1);
                b[xx][yy]=0;
            }
        }
        return;
    }
    int main(){
        cin>>n>>m;
        for(int i=1;i<=n;i++)
            for(int j=1;j<=m;j++)
                cin>>a[i][j]; 
        cin>>startx>>starty>>endx>>endy;
        dfs(startx,starty,0);
        cout<<ans;
        return 0;
    }
    View Code

    最短路径 暴力

    for(int k=1;k<=n;k++){
            for(int i=1;i<=n;i++){
                for(int j=1;j<=n;j++){
                    if(e[i][j]>e[i][k]+e[k][j])
                        e[i][j]=e[i][k]+e[k][j];
                }
            }
        }
    View Code

    底杰斯特拉算法

    #include<bits/stdc++.h>
    
    #define MAX         100                 // 矩阵最大容量
    
     #define INF         (~(0x1<<31))        // 最大值(即0X7FFFFFFF)
     #define LENGTH(a)   (sizeof(a)/sizeof(a[0]))
     // 邻接矩阵
     typedef struct _graph
     {
         char vexs[MAX];       // 顶点集合
         int vexnum;           // 顶点数
         int edgnum;           // 边数
         int matrix[MAX][MAX]; // 邻接矩阵
     }Graph, *PGraph;
     
    
     Graph* create_example_graph()
     {
         char vexs[] = {'A', 'B', 'C', 'D', 'E', 'F', 'G'};
         int matrix[][9] = {
                  /*A*//*B*//*C*//*D*//*E*//*F*//*G*/
           /*A*/ {   0,  12, INF, INF, INF,  16,  14},
           /*B*/ {  12,   0,  10, INF, INF,   7, INF},
           /*C*/ { INF,  10,   0,   3,   5,   6, INF},
           /*D*/ { INF, INF,   3,   0,   4, INF, INF},
           /*E*/ { INF, INF,   5,   4,   0,   2,   8},
           /*F*/ {  16,   7,   6, INF,   2,   0,   9},
           /*G*/ {  14, INF, INF, INF,   8,   9,   0}};
         int vlen = LENGTH(vexs);
         int i, j;
         Graph* pG;
         
         // 输入"顶点数"和"边数"
         if ((pG=(Graph*)malloc(sizeof(Graph))) == NULL )
             return NULL;
         memset(pG, 0, sizeof(Graph));
     
         // 初始化"顶点数"
         pG->vexnum = vlen;
         // 初始化"顶点"
         for (i = 0; i < pG->vexnum; i++)
             pG->vexs[i] = vexs[i];
     
         // 初始化"边"
         for (i = 0; i < pG->vexnum; i++)
             for (j = 0; j < pG->vexnum; j++)
                 pG->matrix[i][j] = matrix[i][j];
     
         // 统计边的数目
         for (i = 0; i < pG->vexnum; i++)
             for (j = 0; j < pG->vexnum; j++)
                 if (i!=j && pG->matrix[i][j]!=INF)
                     pG->edgnum++;
         pG->edgnum /= 2;
     
         return pG;
     }
     
     
     
     
     
     
    
    
     void dijkstra(Graph G, int vs, int prev[], int dist[])
     {
         int i,j,k;
         int min;
         int tmp;
         int flag[MAX];      // flag[i]=1表示"顶点vs"到"顶点i"的最短路径已成功获取。
         
         // 初始化
         for (i = 0; i < G.vexnum; i++)
         {
             flag[i] = 0;              // 顶点i的最短路径还没获取到。
             prev[i] = 0;              // 顶点i的前驱顶点为0。
             dist[i] = G.matrix[vs][i];// 顶点i的最短路径为"顶点vs"到"顶点i"的权。
         }
     
         // 对"顶点vs"自身进行初始化
         flag[vs] = 1;
         dist[vs] = 0;
     
         // 遍历G.vexnum-1次;每次找出一个顶点的最短路径。
         for (i = 1; i < G.vexnum; i++)
         {
             // 寻找当前最小的路径;
             // 即,在未获取最短路径的顶点中,找到离vs最近的顶点(k)。
             min = INF;
             for (j = 0; j < G.vexnum; j++)
             {
                 if (flag[j]==0 && dist[j]<min)
                 {
                     min = dist[j];
                     k = j;
                 }
             }
             // 标记"顶点k"为已经获取到最短路径
             flag[k] = 1;
     
             // 修正当前最短路径和前驱顶点
             // 即,当已经"顶点k的最短路径"之后,更新"未获取最短路径的顶点的最短路径和前驱顶点"。
             for (j = 0; j < G.vexnum; j++)
             {
                 tmp = (G.matrix[k][j]==INF ? INF : (min + G.matrix[k][j])); // 防止溢出
                 if (flag[j] == 0 && (tmp  < dist[j]) )
                 {
                     dist[j] = tmp;
                     prev[j] = k;
                 }
             }
         }
     
         // 打印dijkstra最短路径的结果
         printf("dijkstra(%c): 
    ", G.vexs[vs]);
         for (i = 0; i < G.vexnum; i++)
             printf("  shortest(%c, %c)=%d
    ", G.vexs[vs], G.vexs[i], dist[i]);
     }
     
     
     int main()
     {
         int prev[MAX] = {0};
         int dist[MAX] = {0};
         Graph* pG;
         pG = create_example_graph();
         
         dijkstra(*pG, 3, prev, dist);
         return 0;
         
         
     
     }
     
     
     
     
    View Code

    欧拉筛筛素数

    #include<bits/stdc++.h>
    using namespace std;
    
    void get_prime(vector<int> & prime,int upper_bound){ // 传引用
        if(upper_bound < 2)return;
        vector<bool> Is_prime(upper_bound+1,true);
        for(int i = 2; i <= upper_bound; i++){
            if(Is_prime[i])
                prime.push_back(i);
            for(int j = 0; j < prime.size() and i * prime[j] <= upper_bound; j++){
                Is_prime[ i*prime[j] ] = false;
                if(i % prime[j] == 0)break;// 保证了一个数只被筛一次。
            }
        }
    }
    int main(){
        vector<int> prime;
        get_prime(prime, 1000);
        for(vector<int> :: iterator it = prime.begin(); it not_eq prime.end(); it++)
            cout<<*it<<" ";
        return 0;
    }
    View Code

    读入优化

    #include<bits/stdc++.h>
    using namespace std;
    
    
    int main(){
        ios::sync_with_stdio(0);
        cin.tie(0);
        cout.tie(0);
        int n;
        cin>>n;
        cout<<n;
    }
    View Code
    #include<stdio.h> 
    #include<iostream>
    #include<string.h>
    const int MAX=4e6;
    using namespace std;
    int read(){
        char ch=getchar();
        int x=0,f=1;
        while(ch<'0'||ch>'9'){
            if(ch=='-')f=-1;
            ch=getchar();
        }
        while(ch>='0'&&ch<='9'){
            x=x*10+ch-'0';
            ch=getchar();
        }
        return x*f;
    }
    int main(){
        int x;
        cout<<read();
        return 0;
    }
    View Code

    并查集

    #include<bits/stdc++.h>
    #define ll long long
    using namespace std;
    int a[10000];
    int S(int x){
        if(a[x]==x) return x;
        else{
            a[x]=S(a[x]);
            return a[x];
        }
    }
    void B(int x,int y){
        int xx=S(x);
        int yy=S(y);
        if(xx!=yy)
            a[yy]=xx;
    }
    int main(){
        int n,sum=0;cin>>n;
        for(int i=1;i<=n;i++)a[i]=i;
        for(int i=1;i<=n;i++){
            int x,y;cin>>x>>y;
            B(x,y);
        }
        for(int i=1;i<=n;i++)
            if(a[i]==i)
                sum++;
        cout<<sum;
        return 0;
    }
    View Code

    阶乘高精度

    #include<bits/stdc++.h>
    using namespace std;
    int num[5000];
    int gaojing(int num[],int n){
        int len=1;
        num[0]=1;
        for(int i=1;i<=n;i++){
            len=0;
            int p=0;
            int jw=0;
            while(num[p]!=-1){
                num[p]*=i;
                num[p]+=jw;
                jw=0;
                if(num[p]>=10){
                    jw=num[p]/10;
                    num[p]%=10;
                }
                p++;
                len++;
            }
            if(jw!=0){
                while(jw){
                    num[p++]=jw%10;
                    jw/=10;
                    len++;
                }
            }
        } 
        return len-1;
    }
     
    int main(){
        int n;
        while(cin>>n){
            memset(num,-1,sizeof(num));
            int len=gaojing(num,n);
            for(len;len>=0;len--){
                cout<<num[len];
            }
            cout<<endl;
        }
        return 0;
    }
    View Code

    sort

    字典序

    #include<bits/stdc++.h>
    using namespace std;
    //algorithm
    string a[21];
    bool cmp(string a,string b){
        return a+b > b+a;
    
    int main(){
        int n;cin>>n;
        for(int i=1;i<=n;i++)cin>>a[i];
        sort(a+1,a+n+1,cmp);
        for(int i=1;i<=n;i++)cout<<a[i]<<" ";
        return 0;
    } 

    sstream 和 atoi

    将字符串类型中的最前面数字转换为整数类型

    #include<iostream>
    #include<sstream>
    using namespace std;
    int main(){
        int x;string s;
        cin>>s;
        stringstream ss(s);
        ss>>x;
        cout<<x;
        return 0;
    }
    #include<iostream>
    #include<sstream>
    #include<cstdlib>
    using namespace std;
    int main(){
        int x;string s;
        cin>>s;
        x=atoi(s.c_str());
        cout<<x;
        return 0;
    }

    next_permutation()全排列函数

    #include<iostream>
    #include<string>
    #include<algorithm>
    using namespace std;
    int main(){
        string s="1234567";int sum=0;
        do{
            cout<<s<<'
    ';
            sum++;
        }while(next_permutation(s.begin(),s.end()));
        cout<<sum<<'
    ';
         return 0;
    }
     

    字符串查找函数 直接替代kmp算了

    #include<cstring>
    #include<cstdio>
    #include<iostream>
    using namespace std;
    int main()
    {
        ////find函数返回类型 size_type
        string s("sbjkji");
        string flag;
        string::size_type position;
        //find 函数 返回jk 在s 中的下标位置
        position = s.find("ji");
        if (position != s.npos)  //如果没找到,返回一个特别的标志c++中用npos表示,我这里npos取值是4294967295,
        {
            printf("position is : %d
    " ,position);
        }
        else
        {
            printf("Not found the flag
    ");
        }
        
        position = s.find("good_girl");
        if (position != s.npos) 
        {
            printf("position is : %d
    " ,position);
        }
        else
        {
            printf("Not found the flag
    ");
        }
        
         
        
        
    }
    View Code

    strstr:

    #include<bits/stdc++.h>
    
    /*
     *  strstr函数
     *  功能:在串中查找指定字符串的第一次出现
     *  用法:char *strstr(char *strOne, char *strTwo);
     *  据说strstr函数和KMP的算法效率差不多
     */
    
    int main(int argc, const char * argv[])
    {
        char strOne[] = "Hope my cold is better";
        char strTwo[] = "cold";
        char *ptr;
        ptr = strstr(strOne, strTwo);
        std::cout << ptr << '
    ';
       
        
        //输出  cold is better
        
         return 0;
    }

     优先队列

    #include<iostream>
    #include <queue>
    using namespace std;
    int main()
    {
        //对于基础类型 默认是大顶堆
        priority_queue<int> a;
        //等同于 priority_queue<int, vector<int>, less<int> > a;
    
        //      这里一定要有空格,不然成了右移运算符↓↓
        priority_queue<int, vector<int>, greater<int> > c;  //这样就是小顶堆
        priority_queue<string> b;
    
        for (int i = 0; i < 5; i++)
        {
            a.push(i);
            c.push(i);
        }
        while (!a.empty())
        {
            cout << a.top() << ' ';
            a.pop();
        }
        cout << endl;
    
        while (!c.empty())
        {
            cout << c.top() << ' ';
            c.pop();
        }
        cout << endl;
    
        b.push("abc");
        b.push("abcd");
        b.push("cbd");
        while (!b.empty())
        {
            cout << b.top() << ' ';
            b.pop();
        }
        cout << endl;
        return 0;
        /*
        结果
        4 3 2 1 0
        0 1 2 3 4
        cbd abcd abc
         */ 
        
        
        
        
        
    }
    View Code

    用pair做优先队列元素的例子:

    规则:pair的比较,先比较第一个元素,第一个相等比较第二个。

    #include <iostream>
    #include <queue>
    #include <vector>
    using namespace std;
    int main()
    {
        priority_queue<pair<int, int> > a;
        pair<int, int> b(1, 2);
        pair<int, int> c(1, 3);
        pair<int, int> d(2, 5);
        a.push(d);
        a.push(c);
        a.push(b);
        while (!a.empty())
        {
            cout << a.top().first << ' ' << a.top().second << '
    ';
            a.pop();
        }
    }
    View Code

     字符串和数字的互相转换:

    #include<bits/stdc++.h> 
    using namespace std;
    int main () 
    {
      int a;float b;long c;
      string d,e,f; // char d[10],e[10],f[10];
    
      /* string to number */
      stringstream ss;
      ss << "32";
      ss >> a;
      ss.clear();
    
      ss << "3.1415";
      ss >> b;
      ss.clear();
    
      ss << "567283";
      ss >> c;
      ss.clear();
    
      cout<<a<<","<<b<<","<<c<<endl;
    
      /* number to string */
      ss << a;
      ss >> d;
      ss.clear();
    
      ss << b;
      ss >> e;
      ss.clear();
    
      ss << c;
      ss >> f;
      ss.clear();
    
      cout<<d<<","<<e<<","<<f<<endl;
    
      return 0;
    }
    View Code

    bitset

    #include <iostream>
    #include <bitset>
    
    using namespace std;
    
    const int MAXN = 32;
    
    bitset<MAXN> bt(11);
    
    int main()
    {
        cout << bt << '
    '; // 输出   0000 ....1011 32位 
        
        cout <<bt.count() << '
    ';  //3个1输出3
        
        cout << bt.size()  << '
    '; 
        /*
        bt.flip()       //  把 bt 中所有二进制位逐位取反
        bt.flip(pos)    //  把 bt 中在 pos 处的二进制位取反 
        bt[pos].flip()  //  同上
        bt.set()        //  把 bt 中所有二进制位都置为 1
        bt.set(pos)     //  把 bt 中在 pos 处的二进制位置为 1
        bt.reset()      //  把 bt 中所有二进制位都置为 0
        bt.reset(pos)   //  把 bt 中在pos处的二进制位置为0
        ~ | ^ & 都可以用 
    
        
        
        
        return 0;
    }

     各种进制转换:https://blog.csdn.net/vir_lee/article/details/80645066

    记忆化搜索:

    https://blog.csdn.net/p2718756941/article/details/95473857

    #include <bits/stdc++.h>
    using namespace std;
    int read()
    {
        int x=0,f=1;
        char ch=getchar();//getchar()读入单个字符(包括空格 ,换行符)
        while(ch<'0'||ch>'9'){//非数字(字符)
            if(ch=='-')
                f=-1;
            ch=getchar();
        }
        while(ch>='0'&&ch<='9'){
            x=(x<<1)+(x<<3)+(ch^48);//原二进制数向左平移x位,右边原位置以0补齐(位运算)
            ch=getchar();
        }
        return x*f;
    }//快读
     
     
    int n,m;
    int a[1010][1010];
    int dp[1010][1010];
    int ans;
     
    void CIN()
    {
        n=read();
        m=read();
        for(int i=1;i<=n;i++){
            for(int j=1;j<=m;j++){
                a[i][j]=read();
                dp[i][j]=1;
            } 
        }
        return;
    }
     
    int dir[4][2]={{1,0},{0,1},{-1,0},{0,-1}};
     
    bool in(int x,int y)
    {
        if(x>0&&y>0&&x<=n&&y<=m)return 1;
        return 0;
    }
     
    int DFS(int x,int y){
        if(dp[x][y]>1)return dp[x][y];
        for(int i=0;i<4;i++)
        {
            int xx=x+dir[i][0];
            int yy=y+dir[i][1];
            if(in(xx,yy)&&a[x][y]>a[xx][yy])
                dp[x][y]=max(dp[x][y],DFS(xx,yy)+1);
        }
     
         
        return dp[x][y];
    }
     
    int main(){
        CIN();
        for(int i=1;i<=n;i++)
            for(int j=1;j<=m;j++)
                ans=max(ans,DFS(i,j));
        cout<<ans<<endl;
         
         
        return 0;
    }
    View Code

    埃及分数

    https://www.jianshu.com/p/da04c77e11d0

    import java.io.BufferedReader;
    import java.io.InputStreamReader;
    
    //埃及分数
    public class EgyptFraction {
        public static void main(String[] args) throws Exception{
            BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(System.in));
            System.out.println("输入分子");
            int a = Integer.parseInt(bufferedReader.readLine());
            System.out.println("输入分母");
            int b = Integer.parseInt(bufferedReader.readLine());   //输入ab
    
            int e;
    
            //要求是如果分子大于1就可以拆分
            do {
               e = b/a + 1;
               System.out.println("1/"+e);
    
               a = a * e - b;
               b = b * e;
    
               int maxDiv = maxComDiv(a,b);
               if(maxDiv > 1){
                   a /= maxDiv;
                   b /= maxDiv;
               }
            }while (a > 1);
    
            System.out.println("1/"+b);
        }
    
        private static int maxComDiv(int a, int b) {
            int temp = 0;
            while(b != 0){
                temp = a % b;
                a = b;
                b = temp;
            }
            return a;
        }
    }
    View Code

     十进制转26进制

    #include <bits/stdc++.h>
    using namespace std;
    
    char str[27] = {0,'A','B','C','D','E','F','G','H','I','J','K'
                   ,'L','M','N','O','P','Q','R','S','T','U','V',
                   'W','X','Y','Z'};
    
    int main() {
       int num;
       string ans = "";
       scanf("%d", &num);
       while(num) {
           ans += str[num % 26];
           num /= 26;
       }
       for (int i = ans.size() - 1; i >= 0; i--) {
           cout << ans[i];
       }
       return 0;
    }
    View Code

    数据类型取值范围

     快速读入:

    int read(){
        int x=0,f=1;
        char ch=getchar();//getchar()读入单个字符(包括空格 ,换行符)
        while(ch<'0'||ch>'9'){//非数字(字符)
            if(ch=='-')
                f=-1;
            ch=getchar();
        }
        while(ch>='0'&&ch<='9'){
            x=(x<<1)+(x<<3)+(ch^48);//原二进制数向左平移x位,右边原位置以0补齐(位运算)
            ch=getchar();
        }
        return x*f;
    }
    View Code

    解决爆栈 手动加栈:

    #pragma comment(linker, “/STACK:1024000000,1024000000”)

  • 相关阅读:
    安装触动精灵
    云集微助手安装教程和授权说明old
    造粉神器下载地址
    兵工厂安装和使用教程
    云集微助手-操作简介
    转:二叉树的深度优先遍历和广度优先遍历
    转:背包问题的解法
    Moco搭建测试服务器
    Jmeter的内嵌函数和变量
    Jmeter输出HTML的性能测试报告
  • 原文地址:https://www.cnblogs.com/ranzhong/p/13778980.html
Copyright © 2020-2023  润新知