zoukankan      html  css  js  c++  java
  • HDU1198 Farm Irrigation 农场灌溉 基础题

    这道题目主要是构图,之后就是水水地求连通分量个数了,用广搜,用深搜,用并查集都行,不过并查集效率要高。

    /*
    *State: HDU1198 46MS 372K 2322 B C++ 
    *题目大意:
    *        给定A~K个固定的小方块,方块中有水管,然后要求凑这些小方块成为
    *        一个大矩形,求最后形成的连通分量数目。
    *解题思路:
    *        主要是构图比较特别。枚举每个小方块构图,最后用dfs查连通分量数即可。
    *        图可构为无向图。
    *解题感想:
    *        好像用map慢了许多。第三次优化用了并查集,果然0ms了,连建图都省了
    */

    并查集版本:

    View Code
    //第三次优化
    //State:  HDU1198 0MS 264K 2185 B C++
    //果然求无向图连通分量数,用并查集要快很多
    #include <iostream>
    #include <cstdio>
    #include <cstring>
    using namespace std;
    
    const int MAXN = 2505;
    typedef struct _node
    {
        int up, down, left, right;
        _node():up(0), down(0), left(0), right(0) {};
    }N;
    
    typedef struct _Set
    {
        int parent;
    }Set;
    
    Set mySet[MAXN];
    N sq[11];
    char Map[51][51];
    int dir[4][2] = {{-1, 0}, {0, 1}, {1, 0}, {0, -1}};
    
    void init()
    {
        for(int i = 0; i < MAXN; i++)
            mySet[i].parent = i;
    
        sq[0].up = sq[0].left = 1;
        sq[1].up = sq[1].right = 1;
        sq[2].left = sq[2].down = 1;
        sq[3].down = sq[3].right = 1;
        sq[4].up = sq[4].down = 1;
        sq[5].left = sq[5].right = 1;
        sq[6].left = sq[6].up = sq[6].right = 1;
        sq[7].left = sq[7].up = sq[7].down = 1;
        sq[8].left = sq[8].down = sq[8].right = 1;
        sq[9].up = sq[9].right = sq[9].down = 1;
        sq[10].left = sq[10].up = sq[10].right = sq[10].down = 1;
    }
    
    int findSet(int x)
    {
        if(x != mySet[x].parent)
            mySet[x].parent = findSet(mySet[x].parent);
        return mySet[x].parent;
    }
    
    void Union(int x, int y)
    {
        x = findSet(x);
        y = findSet(y);
        if(x == y)
            return ;
        else
            mySet[y].parent = x;
    }
    
    void bulid(int n, int m)
    {
        int ni, nj;
        for(int i = 0; i < n; i++)
            for(int j = 0; j < m; j++)
            {
                for(int k = 0; k < 4; k++)
                {
                    ni = i + dir[k][0];
                    nj = j + dir[k][1];
                    if(ni >= 0 && ni < n && nj >= 0 && nj < m)
                    {
                        int u = i * m + j;
                        int v = ni * m + nj;
    
                        int ind = Map[i][j] - 'A';
                        int other = Map[ni][nj] - 'A';
    
                        if(sq[ind].up && sq[other].down && k == 0)
                            Union(u, v);
                        if(sq[ind].right && sq[other].left && k == 1)
                            Union(u, v);
                        if(sq[ind].down && sq[other].up && k == 2)
                            Union(u, v);
                        if(sq[ind].left && sq[other].right && k == 3)
                            Union(u, v);
                    }
                }
            }
    }
    
    int main(void)
    {
    #ifndef ONLINE_JUDGE
        freopen("in.txt", "r", stdin);
    #endif
    
        int n, m;
        while(scanf("%d %d", &n, &m), n > 0 && m > 0)
        {
            init();
            
            for(int i = 0; i < n; i++)
                scanf("%s", Map[i]);
            bulid(n, m);
            int tolN = n * m, ans = 0;
            for(int i = 0; i < tolN; i++)
            {
                if(mySet[i].parent == i)
                    ans++;
            }
            printf("%d\n", ans);
        }
        return 0;
    }

    深搜版本:

    View Code
      1 #include <iostream>
      2 #include <vector>
      3 #include <cstdio>
      4 #include <cstring>
      5 using namespace std;
      6 
      7 const int MAXN = 2505;
      8 typedef struct _node
      9 {
     10     int up, down, left, right;
     11     _node():up(0), down(0), left(0), right(0) {};
     12 }N;
     13 
     14 N sq[11];
     15 char Map[51][51];
     16 vector<int> vec[MAXN];
     17 int dir[4][2] = {{-1, 0}, {0, 1}, {1, 0}, {0, -1}};
     18 int vst[MAXN];
     19 
     20 void init()
     21 {
     22     memset(vst, 0, sizeof(vst));
     23     for(int i = 0; i < MAXN; i++)
     24         vec[i].clear();
     25 
     26     sq[0].up = sq[0].left = 1;
     27     sq[1].up = sq[1].right = 1;
     28     sq[2].left = sq[2].down = 1;
     29     sq[3].down = sq[3].right = 1;
     30     sq[4].up = sq[4].down = 1;
     31     sq[5].left = sq[5].right = 1;
     32     sq[6].left = sq[6].up = sq[6].right = 1;
     33     sq[7].left = sq[7].up = sq[7].down = 1;
     34     sq[8].left = sq[8].down = sq[8].right = 1;
     35     sq[9].up = sq[9].right = sq[9].down = 1;
     36     sq[10].left = sq[10].up = sq[10].right = sq[10].down = 1;
     37 }
     38 
     39 void addEdge(int u, int v)
     40 {
     41     vec[u].push_back(v);
     42     vec[v].push_back(u);
     43 }
     44 
     45 void bulid(int n, int m)
     46 {
     47     int ni, nj;
     48     for(int i = 0; i < n; i++)
     49         for(int j = 0; j < m; j++)
     50         {
     51             for(int k = 0; k < 4; k++)
     52             {
     53                 ni = i + dir[k][0];
     54                 nj = j + dir[k][1];
     55                 if(ni >= 0 && ni < n && nj >= 0 && nj < m)
     56                 {
     57                     int u = i * m + j;
     58                     int v = ni * m + nj;
     59 
     60                     int ind = Map[i][j] - 'A';
     61                     int other = Map[ni][nj] - 'A';
     62 
     63                     if(sq[ind].up && sq[other].down && k == 0)
     64                         addEdge(u, v);
     65                     if(sq[ind].right && sq[other].left && k == 1)
     66                         addEdge(u, v);
     67                     if(sq[ind].down && sq[other].up && k == 2)
     68                         addEdge(u, v);
     69                     if(sq[ind].left && sq[other].right && k == 3)
     70                         addEdge(u, v);
     71                 }
     72             }
     73         }
     74 }
     75 
     76 void dfs(int n)
     77 {
     78     vst[n] = 1;
     79     for(unsigned i = 0; i < vec[n].size(); i++)
     80     {
     81         int son = vec[n][i];
     82         if(!vst[son])
     83         {
     84             dfs(son);
     85         }
     86     }
     87 }
     88 
     89 int main(void)
     90 {
     91 #ifndef ONLINE_JUDGE
     92     freopen("in.txt", "r", stdin);
     93 #endif
     94 
     95     int n, m;
     96     while(scanf("%d %d", &n, &m), n > 0 && m > 0)
     97     {
     98         init();
     99         
    100         for(int i = 0; i < n; i++)
    101             scanf("%s", Map[i]);
    102         bulid(n, m);
    103         int tolN = n * m, ans = 0;
    104         for(int i = 0; i < tolN; i++)
    105         {
    106             if(!vst[i])
    107             {
    108                 ans++;
    109                 dfs(i);
    110             }
    111         }
    112         printf("%d\n", ans);
    113     }
    114     return 0;
    115 }
  • 相关阅读:
    python调用go
    manjaro安装qt
    Ubuntu16.04 ROS安装kinect2并获取骨骼数据+配置kinect2_tracker_pd很不专业的博客-程序员宅基地
    Kinect XBOX 360和六轴机械臂的实时映射
    KinectV2.0 VS2019配置记录
    (29条消息) windows下用kinect V2 识别人体骨骼_interstellar-ai的博客-CSDN博客
    Baxter实战:Ubuntu16.04+Kinect2实现动作跟随
    Kinect2和六轴机械臂的实时映射(初步)
    CS395-T: Robot Learning from Demonstration and Interaction
    无需公网IP,远程SSH访问Linux服务器!
  • 原文地址:https://www.cnblogs.com/cchun/p/2641074.html
Copyright © 2011-2022 走看看