zoukankan      html  css  js  c++  java
  • 回溯法练习【BFS/DFS】

    1.N皇后问题
    2.油田问题
    3.素数环问题
    4.马踏棋盘问题
    5.图的m着色问题
    6.01背包问题
    7.TSP问题

    【Code-1:输出N皇后方案和个数】

    #include<bits/stdc++.h>
    using namespace std;
    typedef long long  ll;
    const int maxn = 105;
    const ll INF = 2147483647;
    typedef pair<ll ,int> pli;
    int a[maxn],b[maxn],c[maxn],mp[maxn][maxn];
    int n,cnt;
    void print()
    {
        for(int i=1;i<=n;i++){
            for(int j=1;j<=n;j++)
                printf("%d ",mp[i][j]);
            printf("
    ");
        }
    
    }
    int dfs(int i)
    {
        for(int j=1;j<=n;j++)
        {
            if(!a[j] && !b[i-j+n] && !c[i+j])
            {
                mp[i][j]=i;
                a[j]=b[i-j+n]=c[i+j]=1;
    
                if(i==n)
                {
                    print();
                    printf("
    ");
                    cnt++;
                }
                else
                {
                    dfs(i+1);
                }
    
                mp[i][j]=0;
                a[j]=b[i-j+n]=c[i+j]=0;
            }
        }
    }
    int main()
    {
        scanf("%d",&n);
        dfs(1);
        printf("%d
    ",cnt);
    }
    

    【HDU-2553-N皇后输出方案数/预处理打表】:

    #include<bits/stdc++.h>
    using namespace std;
    typedef long long  ll;
    const int maxn = 105;
    const ll INF = 2147483647;
    typedef pair<ll ,int> pli;
    int a[maxn];
    int cnt=0;
    int vis[3][maxn];
    int n;
    void dfs(int i)
    {
        if(i==n+1)
        {
            cnt++;
            return ;
        }
        for(int j=1;j<=n;j++)
        {
            if(!vis[0][i-j+n] && !vis[1][j] && !vis[2][i+j])
            {
                vis[0][i-j+n] = vis[1][j] = vis[2][i+j] = 1;
                dfs(i+1);
                vis[0][i-j+n] = vis[1][j] = vis[2][i+j] = 0;
            }
        }
    }
    
    
    int main()
    {
        for(n=1;n<=10;n++)
        {
            memset(vis,0,sizeof(vis));
            cnt=0;
            dfs(1);
            a[n]=cnt;
        }
        while(~scanf("%d",&n),n)
        {
            printf("%d
    ",a[n]);
        }
    
    }
    
    

    【Code-2】:HDU 1241

    #include<bits/stdc++.h>
    using namespace std;
    typedef long long  ll;
    const int maxn = 105;
    const ll INF = 2147483647;
    typedef pair<ll ,int> pli;
    //int dir[8][2]={ {0,1},{1,-1},{-1,0},{-1,-1},{-1,0},{-1,1},{0,1},{1,1} };
    int dir[8][2]={1,0,-1,0,0,1,0,-1,1,1,-1,-1,1,-1,-1,1};
    char mp[maxn][maxn];
    int n,m;
    int ok(int x,int y)
    {
        if(x>=0 && y>=0 && x<n && y<m && mp[x][y]=='@')
            return 1;
        return 0;
    }
    void dfs(int x, int y)
    {
        mp[x][y]='*';//把找到的@变为*,以免重复搜索
        for(int i=0;i<8;i++)
        {
            x=x+dir[i][0];
            y=y+dir[i][1];
            if(ok(x,y))
            {
                dfs(x,y);
            }
        }
    }
    int main()
    {
        while(~scanf("%d%d",&n,&m),n&&m)
        {
            //getchar();
            int cnt=0;
            for(int i=0;i<n;i++)
            {
                scanf("%s",mp[i]);
            }
            for(int i=0;i<n;i++)
            {
                for(int j=0;j<m;j++)
                {
                    if(mp[i][j]=='@')
                    {
                        dfs(i,j);
                        cnt++;
                    }
                }
            }
            printf("%d
    ",cnt);
        }
    }
    /*
    5 5
    ****@
    *@@*@
    *@**@
    @@@*@
    @@**@
    */
    
    

    【Code-3-素数环】:

    #include<bits/stdc++.h>
    using namespace std;
    typedef long long  ll;
    const int maxn = 105;
    const ll INF = 2147483647;
    typedef pair<ll ,int> pli;
    int n,cnt;
    int vis[maxn];
    bool isp(int n)
    {
        if(n<=1) return 0;
        else
        {
            for(int i=2;i<=sqrt(n);i++)
            {
                if(n%i==0) return 0;
            }
        }
        return 1;
    }
    int a[maxn];
    /*
    int print()
    {
        cnt++;
        //printf("(%d)
    ",cnt);
        for(int j=1;j<=n;j++)
            printf("%d ",a[j]);
        printf("
    ");
    }
    */
    void dfs(int cur)
    {
    
        if(cur>n && isp(a[1]+a[n]))
        {
            cnt++;
            for(int i=1;i<=n;i++)
                printf("%d ",a[i]);
            printf("
    ");
        }
        else
        {
            for(int i=1;i<=n;i++)
            {
                if(vis[i]==0 && isp(i+a[cur-1]))
                {
                    a[cur]=i;
                    vis[i]=1;
                    dfs(cur+1);
                    vis[i]=0;
                }
            }
        }
    }
    
    int main()
    {
        scanf("%d",&n);
        memset(a,0,sizeof(a));
        dfs(1);
        printf("Total sum is %d
    ",cnt);
    }
    
    

    【Code-4-骑士周游】:

    #include<bits/stdc++.h>
    using namespace std;
    typedef long long  ll;
    const int maxn = 50;
    const ll INF = 2147483647;
    typedef pair<ll ,int> pli;
    
    int n,m;
    int cnt;
    int vis[maxn][maxn];
    int fx[8]={-1,1,-2,2,-2,2,-1,1};
    int fy[8]={-2,-2,-1,-1,1,1,2,2};
    int a[maxn][maxn];
    int f=0;
    struct node
    {
        int x,y;
        node(int a=0,int b=0):x(a),y(b){}
    }path[maxn];
    
    int ok(int x,int y)
    {
        if(x>=1 && y>=1 && x<=n && y<=m && !vis[x][y] && !f)
            return 1;
        return 0;
    }
    
    void print()
    {
        for(int i=1;i<=n*m;i++){
                int x=path[i].x;
                int y=path[i].y;
                printf("%d %d
    ",y,x); //输出坐标
            }
    }
    void dfs(int x, int y, int d)
    {
        path[d]=node(x,y);
        if(d==n*m)
        {
            f=1;
            return ;
        }
        for(int i=0;i<8;i++)
        {
            int xx=x+fx[i];
            int yy=y+fy[i];
            if(ok(xx,yy))
            {
                vis[xx][yy]=1;
                dfs(xx,yy,d+1);
                vis[xx][yy]=0;
            }
        }
    
    }
    int main()
    {
        f=0;
        memset(vis,0,sizeof(vis));
        scanf("%d%d",&n,&m);
        vis[1][1]=1;
        dfs(1,1,1);
        if(!f) puts("No");
        else print();
    }
    

    【Code-5:洛谷-图的m着色问题】

    #include<bits/stdc++.h>
    using namespace std;
    typedef long long  ll;
    const int maxn = 50;
    const ll INF = 2147483647;
    typedef pair<ll ,int> pli;
    
    int n,m;
    int a[maxn][maxn],c[maxn];
    int sum=0;
    
    int ok(int i)
    {
        for(int j=1;j<=n;j++)
        {
            if(a[i][j] && c[i]==c[j])
                return 0;
        }
        return 1;
    }
    
    void dfs(int cur)
    {
        if(cur==n+1)
        {
            sum++;
            for(int i=1;i<=n;i++)
                printf("%d ",c[i]);
            printf("
    ");
            return ;
        }
        else
        {
            for(int i=1;i<=m;i++)
            {
                c[cur]=i;
                if(ok(cur))
                {
                    dfs(cur+1);
                }
                c[cur]=0;
            }
        }
    }
    
    int main()
    {
        int x,y,k;
        scanf("%d%d%d",&n,&k,&m);
        while(k--)
        {
            scanf("%d%d",&x,&y);
            a[x][y]=a[y][x]=1;
        }
        dfs(1);
        if(!sum) puts("No");
        else printf("%d
    ",sum);
    }
    /*
    5 8 4
    1 2
    1 3
    1 4
    2 3
    2 4
    2 5
    3 4
    4 5
    
    48
    */
    

    【Code6-01背包回溯版】:

    #include<bits/stdc++.h>
    using namespace std;
    typedef long long  ll;
    const int maxn = 2*1e5+5;
    const ll INF = 2147483647;
    typedef pair<ll ,int> pli;
    
    //int v[maxn],w[maxn];
    int n,c,cp,bestp;//物品数、背包大小、当前价值、最优价值
    int x[maxn],bestx[maxn];//当前解、最优解
    struct node
    {
        int v,w;//价值、重量
    }a[maxn];
    bool cmp(node a, node b)
    {
        return a.v*b.w > b.v*a.w;
    }
    void print()
    {
        for(int i=0;i<n;i++)
            printf("%d ",bestx[i]);
        printf("
    "); return ;
    }
    void dfs(int cur)
    {
        if(cur>=n)
        {
            if(bestp<cp)
                bestp=cp;
            for(int i=0;i<n;i++)
                bestx[i]=x[i];
            //print();
        }
        else
        {
            if(a[cur].w <= c)
            {
                x[cur]=1; cp+=a[cur].v; c-=a[cur].w;
                dfs(cur+1);
                x[cur]=0; c+=a[cur].w; cp-=a[cur].v;
            }
            x[cur]=0;
            dfs(cur+1);
        }
    }
    
    int main()
    {
        scanf("%d%d",&n,&c);
        for(int i=0;i<n;i++)
            scanf("%d",&a[i].v);
        for(int i=0;i<n;i++)
            scanf("%d",&a[i].w);
        sort(a,a+n,cmp);
        dfs(0);
        printf("%d
    ",bestp);
    }
    /*
    5 10
    6 3 6 5 4
    2 2 4 6 5
    
    最优价值 15
    放入   1 2 3
    
    
    3 30
    16 10 13
    45 20 25
    */
    
    

    【输出路径版】

    #include<bits/stdc++.h>
    using namespace std;
    typedef long long  ll;
    const int maxn = 2*1e5+5;
    const ll INF = 2147483647;
    typedef pair<ll ,int> pli;
    
    int w[maxn];  
    int v[maxn];  
    int best_ans[maxn], ans[maxn];  
    int cw, cv, n, max_w, max_v ;
    void print()  
    {  
        printf("%d
    ",max_v);  
        for(int i=0;i<n;i++)  
            printf("%d ",best_ans[i]);  
        printf("
    ");  
    }  
      
    void DFS(int step,int cw,int cv)  
    {  
        if(step>=n)  
        {  
            if(cv > max_v)  
            {   
                max_v = cv;
                for(int i=0;i<n;i++)  
                    best_ans[i] = ans[i];  
            }  
        }  
        else  
        {  
            if(cw >= w[step])  
            {   
                ans[step] = 1;  cv += v[step]; cw -= w[step];  
                DFS(step+1,cw,cv);  
                ans[step] = 0;  cv -= v[step]; cw += w[step]; 
            }  
            ans[step]=0;
            DFS(step+1,cw,cv);  
        }  
    }  
      
    void init()  
    {  
        max_v = 0;  
        for(int i=0;i<n;i++)  
            ans[i] = 0;  
        max_v = 0;
    }  
      
    int main()  
    {  
        while(scanf("%d%d",&n,&max_w)!=EOF)  
        {  
            for(int i=0;i<n;i++)  
                scanf("%d",&v[i]);  
            for(int j=0;j<n;j++)  
                scanf("%d",&w[j]);  
            init();  
            DFS(0,max_w,0);  
            print();       
        }  
        return 0; 
    }  
    /*
    5 10
    6 3 6 5 4
    2 2 4 6 5
    
    */
    
  • 相关阅读:
    Mac Outlook邮箱MicrosoftExchange邮箱快满了,请减小邮箱大小。
    SpringCloud Config Server中{application}等占位符使用场景设置默认拉去分支
    五四日记
    org.apache.ibatis.binding.BindingException: Mapper method 'attempted to return null from a method with a primitive return type (long).
    业务量剧增后服务器常见返回码总结
    Mac下Jmeter快速安装与入门-模拟测试Post请求及设置Http头
    Mac下 Visual VM 无法检测到本地的Java进程
    高并发下hystrix熔断超时及concurrent.RejectedExecutionException: Rejected command because thread-pool queueSize is at rejection threshold问题
    Silly Java-Final 关键字
    qqwry.dat输出乱码问题及maven打包后资源文件大小不一致的问题
  • 原文地址:https://www.cnblogs.com/Roni-i/p/9138706.html
Copyright © 2011-2022 走看看