zoukankan      html  css  js  c++  java
  • zoj 2412 dfs

    链接:http://acm.zju.edu.cn/onlinejudge/showProblem.do?problemCode=2412

    题意:有11种不同的水管,如果它们能连通,则可以流水,求一块地上连通水管数。

    思路:这题主要是先要把不同的水管表示出来,一开始觉得要表示出来很麻烦,后面去看了别人写的。地有四个方向,某个方向上有水管则为1,没有为0,这样就表示出来了。然后在搜索过程中,如果当前的地在某个方向i上有水管,则看相邻的地在对应的方向(i+2)%4上有无水管,有的话继续搜下去,没有就不搜咯。其他部分和zoj的1709差不多,用一个visited数组来记录某块地有没有被搜过,0为没被搜,1为被搜过。

    #include<cstdio>
    #include<cstring>
    
    const int maxn=52;
    int map[maxn][maxn];
    int dir[4][2]={{-1,0},{0,1},{1,0},{0,-1}};
    int type[11][4]={{1,0,0,1},{1,1,0,0},{0,0,1,1},{0,1,1,0},{1,0,1,0},
    {0,1,0,1},{1,1,0,1},{1,0,1,1},{0,1,1,1},{1,1,1,0},{1,1,1,1}};//水管类型
    int m,n;
    int visited[maxn][maxn];
    
    void dfs(int x,int y)
    {
        visited[x][y]=1;
        int xx,yy;
        for(int i=0;i<4;i++)
        {
            if(type[map[x][y]][i]==0) continue;
            xx=x+dir[i][0];yy=y+dir[i][1];
            if(xx<0 || xx>=m || yy<0 || yy>=n) continue;
            if(visited[xx][yy]==1) continue;
            if(type[map[xx][yy]][(i+2)%4]==1)
               dfs(xx,yy);
        }
    }
    int main()
    {
        int cnt;
        char c;
        while(scanf("%d%d",&m,&n) && m>0 && n>0)
        {
            memset(visited,0,sizeof(visited));
            cnt=0;
            getchar();
            for(int i=0;i<m;i++)
            {
                for(int j=0;j<n;j++)
                {
                    scanf("%c",&c);
                    map[i][j]=c-'A';//变为数字
                }
                getchar();
            }
            for(int i=0;i<m;i++)
               for(int j=0;j<n;j++)
                   if(visited[i][j]==0)
                   {
                       dfs(i,j);
                       cnt++;
                   }
            printf("%d\n",cnt);
        }
        return 0;
    }

    在写的过程中老是有些小错误,表示很内伤啊。。。。

    下面的代码是用了map来把字母A,B等映射为数字。功能和上面的map[i][j]=c-'A'一样。纯属无聊。

    #include<cstdio>
    #include<cstring>
    #include<map>
    using namespace std;
    const int maxn=52;
    int s[maxn][maxn];
    int dir[4][2]={{-1,0},{0,1},{1,0},{0,-1}};
    int type[11][4]={{1,0,0,1},{1,1,0,0},{0,0,1,1},{0,1,1,0},{1,0,1,0},
    {0,1,0,1},{1,1,0,1},{1,0,1,1},{0,1,1,1},{1,1,1,0},{1,1,1,1}};//水管类型
    map<char,int> ma;
    int m,n;
    int visited[maxn][maxn];
    void dfs(int x,int y)
    {
        visited[x][y]=1;
        int xx,yy;
        for(int i=0;i<4;i++)
        {
            if(type[s[x][y]][i]==0) continue;
            xx=x+dir[i][0];yy=y+dir[i][1];
            if(xx<0 || xx>=m || yy<0 || yy>=n) continue;
            if(visited[xx][yy]==1) continue;
            if(type[s[xx][yy]][(i+2)%4]==1)
               dfs(xx,yy);
        }
    }
    int main()
    {
        int cnt;
        char c;
        for(int i=0;i<11;i++)
        {
            ma['A'+i]=i;
        }
        while(scanf("%d%d",&m,&n) && m>0 && n>0)
        {
            memset(visited,0,sizeof(visited));
            cnt=0;
            getchar();
            for(int i=0;i<m;i++)
            {
                for(int j=0;j<n;j++)
                {
                    scanf("%c",&c);
                    s[i][j]=ma[c];//变为数字
                }
                getchar();
            }
            for(int i=0;i<m;i++)
               for(int j=0;j<n;j++)
                   if(visited[i][j]==0)
                   {
                       dfs(i,j);
                       cnt++;
                   }
            printf("%d\n",cnt);
        }
        return 0;
    }

    另外,此题用并查集做也可以。还是要先把11种水管表示出来,然后可以连通的水管就合并在一个集合中,统计各个集合中元素个数,再求和。代码就不写了。

  • 相关阅读:
    【数据结构】线性表&&顺序表详解和代码实例
    【智能算法】超详细的遗传算法(Genetic Algorithm)解析和TSP求解代码详解
    【智能算法】用模拟退火(SA, Simulated Annealing)算法解决旅行商问题 (TSP, Traveling Salesman Problem)
    【智能算法】迭代局部搜索(Iterated Local Search, ILS)详解
    10. js时间格式转换
    2. 解决svn working copy locked问题
    1. easyui tree 初始化的两种方式
    10. js截取最后一个斜杠后面的字符串
    2. apache整合tomcat部署集群
    1. apache如何启动
  • 原文地址:https://www.cnblogs.com/54zyq/p/3077463.html
Copyright © 2011-2022 走看看