zoukankan      html  css  js  c++  java
  • MinimumTours TopCoder

    Problem Statement

         Little Bonnie has taken a vacation to Ha Long Bay. There are a few thousand stone islands in the bay, making it one of the most beautiful natural scenes in Vietnam. Bonnie is so impressed by this fact that she has decided to visit all of the islands. She bought a map of all the islands in the bay. This map is given in the String[] islandMap, which is a two-dimensional matrix where each cell is either '.' or lowercase 'x'. '.' cells represent sea and 'x' cells represent land. Two cells are connected if they have a point in common, so each cell may connect to at most 8 other cells. An island is defined as a maximal connected group of 'x' cells. A trip between two islands is defined as a connected group of '.' cells where, for each of the two islands, there is at least one '.' cell in the trip which is connected to a cell in that island. If there is no such connected group of '.' cells between two islands, then there is no trip between them. Note that an island can be nested inside another island. A tour is a sequence of islands where there is a trip between every pair of consecutive islands in the sequence. Little Bonnie wants to visit every island exactly once, and she wants to do this using the minimum possible number of tours. Return the number of tours she will have to take.
     

    Definition

        
    Class: MinimumTours
    Method: getMinimumTours
    Parameters: String[]
    Returns: int
    Method signature: int getMinimumTours(String[] islandMap)
    (be sure your method is public)
        
     
     

    Notes

    - It is possible for a tour to have only one island.
    - Bonnie cannot leave the mapped area at any time.
    - It is assumed that Bonnie has another way to travel from the last island of one tour to the first island of another tour, so you don't have to take this into account when solving the problem.
     

    Constraints

    - islandMap will contain between 1 and 50 elements, inclusive.
    - Each element of islandMap will contain between 1 and 50 characters, inclusive.
    - Each element of islandMap will contain the same number of characters.
    - Each character in islandMap will be either '.' or lowercase 'x'.
    - There will be at least one island in the map.
     

    Examples

    0)  
        
    {
    "..x..x..x..",
    "..x..x..x..",
    "..x..x..x..",
    "..x..x..x.."
    }
    Returns: 1
    Only one tour is needed. Bonnie can just go from the leftmost island through the middle one to the rightmost island. Or she can choose to go in the reverse way.
    1)  
        
    {
    "x....x....x",
    ".....x.....",
    ".....x.....",
    ".....x.....",
    "xxxxxxxxxxx",
    ".....x.....",
    ".....x.....",
    ".....x.....",
    "x....x....x"
    }
    Returns: 3
    At least three tours are required to cover the five islands. One possible set of three tours is to go from the small island in the top-left corner through the big cross-shaped island to the top-right island, and each of the two other islands makes up a one-island tour.
    2)  
        
    {
    "x....x....x",
    ".....x.....",
    ".....x.....",
    "....x.x....",
    "xxxx...xxxx",
    "....x.x....",
    ".....x.....",
    ".....x.....",
    "x....x....x"
    }
    Returns: 1
    There is always a trip between any two islands. So only one tour is enough to visit all five islands.
    3)  
        
    {
    "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx",
    "x............................x",
    "x..xxxxxxxxxx....xxxxxxxxxx..x",
    "x..x........x....x........x..x",
    "x..x..xxxx..x....x.xxxxxx.x..x",
    "x..x........x....x.x....x.x..x",
    "x..xxxxxxxxxx....x.x.x..x.x..x",
    "x................x.x....x.x..x",
    "x................x.xxxxxx.x..x",
    "x..xxxxxxxxxx....x........x..x",
    "x..x........x....x........x..x",
    "x..x..xxxx..x....x.xxxxxx.x..x",
    "x..x........x....x........x..x",
    "x..xxxxxxxxxx....xxxxxxxxxx..x",
    "x............................x",
    "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
    }
    Returns: 2
    An island can be nested inside another one. And two tours are needed in this example.
    4)  
        
    {
    "xxxxxxxxxxxxx....xxxxxxxxxxxxxxxxxxxxxx",
    "x...........x....x.....................",
    "x.xxxxxxxxx.x....x.xxxxxxxxxxxxxxxxxxx.",
    "x.x.......x.x....x.x.................x.",
    "x.x.xxxxx.x.x....x.x.xxxxxxxxxxx.....x.",
    "x.x...x...x.x....x.x.x..........x....x.",
    "x.x...x...x.x....x.x.x.xxx..xxx...x..x.",
    "x.x.......x.x....x.x.x.x....x..x..x..x.",
    "x.xxxxxxxxx.x....x.x.x.xxx..x..x..x..x.",
    "x...........x....x.x.x.x....x..x..x..x.",
    "xxxxxxxxxxxxx....x.x.x.xxx..xxx...x..x.",
    "x................x.x.x......xx....x..x.",
    "x................x.x.x......x.x...x..x.",
    "x................x.x.x......x..x..x..x.",
    "x................x.x.x...........x...x.",
    "x................x.x.xxxxxxxxxxxx....x.",
    "x................x.x.................x.",
    "x................x.xxxxxxxxxxxxxxxxxxx.",
    "x................x.....................",
    "x................xxxxxxxxxxxxxxxxxxxxxx"
    }
    Returns: 1

    传送门

    代码

    //将每一片海和岛看做一个点,构图发现这是一棵树
    #include<iostream>
    #include<cstdio>
    #include<cstring>
    #include<string>
    #include<algorithm>
    #include<cctype>
    #include<cmath>
    #include<cstdlib>
    #include<queue>
    #include<ctime>
    #include<vector>
    #include<set>
    #include<map>
    #include<stack>
    using namespace std;
    const int dx[]={-1,-1,-1,0,0,1,1,1};
        const int dy[]={-1,0,1,-1,1,-1,0,1};
        string s[60];
        int a[1000][1000];
        int n,m,cnt,wt,ans;
        int head[100000];
        bool used[3000][3000],is[100000],gone[100000];
        struct edge{
              int next,to;
        }e[100000];
    class MinimumTours
    {
    public:
        //TC的格式
        void ff(int x,int y,int col,int k){
              if(a[x][y]!=k)return;
              a[x][y]=col;
              for(int i=0;i<8;i++)
                 ff(x+dx[i],y+dy[i],col,k);
        }
        void add(int u,int v){
              e[++wt].next=head[u];
              head[u]=wt;
              e[wt].to=v;
              e[++wt].next=head[v];
              head[v]=wt;
              e[wt].to=u;
        }
        int work(int v){
              /*返回值含义:
                0--对答案无贡献
                1--有一条链,可向上走
                2--是一个单点
              */
              int i,k,cnt1=0,cnt2=0;
              gone[v]=1;
              for(i=head[v];i;i=e[i].next){
                   k=e[i].to;
                 if(!gone[k]){
                     k=work(k);
                     if(k==1)cnt1++;
                     if(k==2)cnt2++;
                 }
              }
              if(is[v]){
                  if(cnt1){
                      ans+=cnt1-1;
                      if(cnt1==1)return 1;
                        else return 0;
                  }
                  else {
                      if(cnt2)return 0;
                      return 2;
                  }
              }
              else {
                  if(cnt1==0)return cnt2>0;
                  ans+=cnt1/2;
                  return ((cnt1&1)?1:2);
              }
        }
        int getMinimumTours(vector<string>islandMap)
        {     //freopen("1.in","r",stdin);
              int i,j,k;
              cnt=0;wt=0;ans=0;
              memset(head,0,sizeof(head));
              n=islandMap.size();
              m=islandMap[0].size();
              for(i=0;i<n;i++)
                 for(j=0;j<m;j++)
                    a[i][j]=(islandMap[i][j]=='.'?-2:-1);
              memset(used,0,sizeof(used));
              memset(is,0,sizeof(is));
              //构图
              for(i=0;i<n;i++)
                 for(j=0;j<m;j++)
                    if(a[i][j]==-1){
                      ff(i,j,++cnt,-1);
                      is[cnt]=1;
                    }   
              for(i=0;i<n;i++)
                 for(j=0;j<m;j++)
                    if(a[i][j]==-2)ff(i,j,++cnt,-2);
              for(i=0;i<n;i++)
                 for(j=0;j<m;j++)
                    for(k=0;k<8;k++){
                        int x1=i,x2=i+dx[k],y1=j,y2=j+dy[k];
                        int p=a[x1][y1],q=a[x2][y2];
                        if(p!=q&&q>0&&!used[p][q]){
                            used[p][q]=used[q][p]=1;
                            add(p,q);
                        }
                    }
              memset(gone,0,sizeof(gone));
              if(work(1)&&is[1])ans+=1;
              return ans;
        }
    };

  • 相关阅读:
    VS提示“项目文件" "已被重命名或已不在解决方案中”的解决办法 .
    微信公众平台教程和SDK收集
    “SQLServerAgent当前未运行”问题解决
    $(document).click() 在苹果手机上不能正常运行
    友盟iOS推送配置(从真机调试到推送)
    Ubuntu安装VMware Tools的方法
    TortoiseSVN客户端如何更改新的URL
    Windows Server 2008系统如何取消登录时要按Ctrl+Alt+Delete组合键
    Windows Server 2008 显示桌面图标
    用WinRAR进行安装包的制作
  • 原文地址:https://www.cnblogs.com/yzxverygood/p/8438017.html
Copyright © 2011-2022 走看看