Java算法---求面积

来源:互联网 发布:淘宝要交保证金吗2017 编辑:程序博客网 时间:2024/04/29 06:03

           今天在做牛客网编程题时遇到了这样一个问题,分享一下:

题目描述:

       给你一张n*m的西湖地图二值图,其中西湖的轮廓用1表示,轮廓内核轮廓外均用0表示。
现在请你统计西湖的面积,即轮廓内0的个数。

输入描述:

       输入包含多组数据,每组数据第一行包含两个正整数n(3≤n≤10)和m(3≤m≤10)。紧接着有n行,每行m个数字,代表地图,数字之间无空格。数据保证只有一片连续的湖泊。

输出描述:

对应每一组数据,输出西湖的面积。

测试用例:

10 10
0000000000
0001101000
0010010100
0010000010
0100000010
0100000100
0010001000
0010001000
0011010000
0000100000
26

下面分析一下这道题,做过类似题的一下就能看出来这道题是用广搜做的,是的,这道题就是用广搜做,我刚开始的思路是这样:从地图的(0,0)点出发开始广搜,如果访问的该点是"0",我们将其标记为"1";如果是"1",就说明该点已经访问过了,这样我们会发现搜索完了以后,这个湖泊以外的部分全部都变成"1"了,那么我们将这个问题就转化为求二维数组中"0"的个数,即是西湖的面积。思路很简单,但是这样的想法会出现这样一个问题,下面我们详细说说这个思路的问题:

假如我们的地图是这样的:

5 5
10001
01110
01010
01110
10001

  对于上述地图,如果用上面的思路,我们会发现一个问题,就是广搜只能将地图中的(1,0),(2,0),(3,0),(0,1),(0,2),(0,3),这六个点变为"1",这样输出的结果为7,显然我们从图上看到,西湖的面积为1,那么问题到底在哪呢?在采用上面思路中,其实我们必须要让地图满足一个条件,那就是除了西湖之外的面积必须是连通的,这样的话,我们才能通过广搜将西湖之外的面积变为"1",然而在下面这个测试用例中,我们发现,西湖之外的部分被"1"阻隔断了,那么当用广搜的时候只能搜索到上述的六个点,其余的搜不到(因为不连通),导致了输出的错误。

针对上述问题,我们应该采取怎样的措施呢?我的思路是这样的,题目给的测试用例用可能不连通,但是我们可以采取办法让他们连通,我采取的办法是,给地图的四个外围方向都加一圈"0",这样我们就可以保证除西湖之外的部分连通,那么我们就可以采用之前的思路解决这个问题了。比如上面测试用例,加一圈"0",就会变成这样:

0000000
0100010
0011100
0010100
0011100
0100010
0000000

  这样观察这个地图就会发现西湖之外的面积都是连通的,广搜都可以搜索到,搜索过的地方标注"1",之后就求出这个地图中"0"的个数,即是西湖的面积,下面贴上自己的代码:

import java.util.*;/** * Created by 华夏紫云 on 2015/11/23. */public class Main {    public static void main(String[] args) {       Scanner sc=new Scanner(System.in);        while (sc.hasNext()) {            int n=sc.nextInt();            int m=sc.nextInt();            int[][] map=new int[n+2][m+2];            for(int i=1;i<n+1;i++){                String str=sc.next();                for (int j=1;j<m+1;j++){                    map[i][j]=Integer.parseInt(String.valueOf(str.charAt(j-1)));                }            }            System.out.println(Wid(n,m,map));            }        }     public static   int Wid(int n,int m,int[][]map){         int[][] dir={{1,0},{-1,0},{0,1},{0,-1}};//定义四个方向         Node start=new Node();         Node local=new Node();         start.x=0;         start.y=0;         Queue<Node> queue=new LinkedList<Node>();         queue.offer(start);         while (!queue.isEmpty()){             local=queue.remove();             for(int i=0;i<4;i++){                 Node nbr=new Node();                 nbr.x=local.x+dir[i][0];                 nbr.y=local.y+dir[i][1];                 if(nbr.x>=0&&nbr.y>=0&&nbr.x<(n+2)&&nbr.y<(m+2)&&map[nbr.x][nbr.y]==0){                     queue.offer(nbr);                     map[nbr.x][nbr.y]=1;                 }             }         }         int count=0;         for(int i=0;i<n;i++){             for(int j=0;j<m;j++){                 if(map[i][j]==0){                     count++;                 }             }         }         return count;     }    }class Node{    int x;    int y;}
       初学者,见谅,如有什么问题,欢迎评论。

0 0
原创粉丝点击