zoukankan      html  css  js  c++  java
  • UVA 291 The House Of Santa Claus (DFS求一笔画)

    题意:从左下方1开始,一笔画出圣诞老人的屋子(不过话说,圣诞老人的屋子是这样的吗?这算是个屋子么),输出所有可以的路径。

    思路:贴代码。

    #include <iostream>
    #include <stdio.h>
    #include <string.h>
    #include <algorithm>
    #include <queue>
    
    using namespace std;
    int head[20],tot=0,val;//val:用整型值存储结果,因为最后输出是要按大小排序
    int vis[20];//用来标记边是否已经走过,若已经走过,则接下来就不能走该条边
    int len;//满足一笔画的答案个数
    int ans[510];//存储答案
    struct Edge{
        int to,next;
    }edge[20];
    
    //建立双向边
    void add(int u,int v){
        edge[tot].next=head[u];
        edge[tot].to=v;
        head[u]=tot++;
    
        edge[tot].next=head[v];
        edge[tot].to=u;
        head[v]=tot++;
    }
    
    void init(){
        memset(head,-1,sizeof(head)); //一开始忘记初始化head了。。。
        add(1,5);add(1,3);add(1,2);
        add(2,5);add(2,3);
        add(3,5);add(3,4);
        add(4,5);
    }
    //u:当前走到的点;idx表示已经走过了idx条边,总计需要走完8条边
    void dfs(int u,int idx){
        if(idx==8){
            val=val*10+u;
            ans[len++]=val;
            val/=10;
            return;
        }
        for(int k=head[u];k!=-1;k=edge[k].next){
            if(vis[k])
                continue;   //若第k条边已经走过,则继续尝试其它边
            int v=edge[k].to;
            /*
            因为是双向边,相同端点的会有两条,走过其中一条后,另一条也要标记走过,因为每条边只能走一次,一开始就是这里给忽略了。
            若k为偶数,第k边端点为u、v,则第k+1边端点也为u、v,要同时标记走过。
            若k为奇数,第k边端点为u、v,则第k-1边端点也为u、v,要同时标记走过。
            */
            if(k%2==0){
                vis[k]=1;
                vis[k+1]=1;
            }
            else{
                vis[k]=1;
                vis[k-1]=1;
            }
            val=val*10+u;
            dfs(v,idx+1);
            //最后要恢复原来的值,不能影响之后的遍历
            val=val/10;
            if(k%2==0){
                vis[k]=0;
                vis[k+1]=0;
            }
            else{
                vis[k]=0;
                vis[k-1]=0;
            }
        }
    }
    
    int main()
    {
        init();
        len=0;
        memset(vis,0,sizeof(vis));
        val=0;
        //从左下角1开始dfs
        dfs(1,0);
    
        sort(ans,ans+len);
        for(int i=0;i<len;i++)
            printf("%d
    ",ans[i]);
        return 0;
    }

    贴个书上的参考程序:

    #include <iostream>
    #include <string>
    #include <cstring>
    //因为数据量很小,用邻接矩阵,15ms,而且输出顺序即按照大小顺序排。
    using namespace std;
    int edge[6][6];
    void makeEdge(){
        memset(edge,0,sizeof(edge));
        for(int i=1;i<=5;i++){
            for(int j=1;j<=5;j++){
                if(i!=j)
                    edge[i][j]=1;
            }
        }
        edge[4][1]=edge[1][4]=0;
        edge[4][2]=edge[2][4]=0;
    }
    //目前已画了k条边,准备将x扩展为s的第k+1条边的端点
    void dfs(int x,int k,string s){
        s+=char(x+'0');
        if(k==8){
            cout<<s<<endl;
            return;
        }
        for(int y=1;y<=5;y++){
            if(edge[x][y]){
                edge[x][y]=edge[y][x]=0;
                dfs(y,k+1,s);
                edge[x][y]=edge[y][x]=1;
            }
        }
    }
    int main()
    {
        makeEdge();
        dfs(1,0,"");
        return 0;
    }
  • 相关阅读:
    服务器图片等资源在8080端口保存
    thinkphp 3.2.1 URL 大小写问题 下面有具体说明
    linux samba smb 在客户端无法连接使用
    php连接redis服务
    服务器死机 导致 mongo 挂掉
    同一个页面引用不同版本jquery库
    CSS3阴影 box-shadow的使用和技巧总结
    php 中使用正则
    Hbase-1.1.1-java API
    hive1.2.1问题集锦
  • 原文地址:https://www.cnblogs.com/chenxiwenruo/p/3365448.html
Copyright © 2011-2022 走看看