hdu1241 求联通快(java)
2017-09-02 22:36
746 查看
GeoSurvComp地质调查公司负责探测地下石油储量。GeoSurvComp公司在一段时间内在一大块矩形区域内工作,创造出一个网格把土地分成很多方块。如果每一方块单独分析,使用感应设备去测定方块中是否含有石油。含有油的方块称为口袋。如果两个口袋是相邻的,那它们属于同一个油床。油床可以相当大,可以包含众多口袋。你的任务就是测定出有多少不同的油床。
输入:
输入文件包括一个或多个网格。每一个网格输入的第一行含有m和n,分别代表网格的横坐标和纵坐标,被一个空格分开。如果m=0则标志着输入结束;否则1<=m<=100并且1<=n<=100。接下来输入m行n列个网格特征(不记录换行符)。每一个特征值跟一个方块相对应,并且要么是*(代表没油),要么是@代表一个石油口袋。
输出:
对于每一个方块,输出不同的油田数。两个不同的口袋属于同一个油田,如果它们垂直水平或对角相邻。一个油田包含少于100个口袋。
解题思路:遍历所有点,求出连通块的数量,每到一块油田,就采用DFS或者BFS消除该油田以及附近连通的油田。
简单dfs(直接上代码)
package 简单搜索;
import java.util.Scanner;
/**
* Created by user on 2017/8/23.
*/
public class hdu1241 {
/**
* 联通快
*/
static int MAX_N=100+2;
static char map[][]=new char[MAX_N][MAX_N];
static int n,m;
static boolean vis[][]=new boolean[MAX_N][MAX_N];//用来标记是否是联通快
static int dir[][] = {{-1,-1},{-1,0},{-1,1},{0,-1},{0,1},{1,-1},{1,0},{1,1}};
public static void main(String args[]){
Scanner scanner=new Scanner(System.in);
while (scanner.hasNext()){
n=scanner.nextInt();
m=scanner.nextInt();
if(n+m==0){
break;
}
scanner.nextLine();
for(int i=0;i<n;i++){
String str=scanner.nextLine();
char a[]=str.toCharArray();
for(int j=0;j<m;j++){
map[i][j]=a[j];
}
}
int sum=0;
init();
for(int i=0;i<n;i++){
for(int j=0;j<m;j++){
if(!vis[i][j]&&map[i][j]=='@'){//当从每个点出发搜索的时候 都会标记以改点扩散的油田 当从下个点搜索的时候
sum++;//就直接不搜索改点
dfs(i,j);
}
}
}
System.out.println(sum);
}
}
private static void dfs(int x, int y) {
vis[x][y]=true;
for(int i=0;i<8;i++){
int dx=x+dir[i][0];
int dy=y+dir[i][1];
if(dx>=0&&dx<n&&dy>0&&dy<m&&!vis[dx][dy]&&map[dx][dy]=='@'){
dfs(dx,dy);
}
}
}
private static void init() {
for(int i=0;i<MAX_N;i++){
for (int j=0;j<MAX_N;j++){
vis[i][j]=false;
}
}
}
}
输入:
输入文件包括一个或多个网格。每一个网格输入的第一行含有m和n,分别代表网格的横坐标和纵坐标,被一个空格分开。如果m=0则标志着输入结束;否则1<=m<=100并且1<=n<=100。接下来输入m行n列个网格特征(不记录换行符)。每一个特征值跟一个方块相对应,并且要么是*(代表没油),要么是@代表一个石油口袋。
输出:
对于每一个方块,输出不同的油田数。两个不同的口袋属于同一个油田,如果它们垂直水平或对角相邻。一个油田包含少于100个口袋。
解题思路:遍历所有点,求出连通块的数量,每到一块油田,就采用DFS或者BFS消除该油田以及附近连通的油田。
简单dfs(直接上代码)
package 简单搜索;
import java.util.Scanner;
/**
* Created by user on 2017/8/23.
*/
public class hdu1241 {
/**
* 联通快
*/
static int MAX_N=100+2;
static char map[][]=new char[MAX_N][MAX_N];
static int n,m;
static boolean vis[][]=new boolean[MAX_N][MAX_N];//用来标记是否是联通快
static int dir[][] = {{-1,-1},{-1,0},{-1,1},{0,-1},{0,1},{1,-1},{1,0},{1,1}};
public static void main(String args[]){
Scanner scanner=new Scanner(System.in);
while (scanner.hasNext()){
n=scanner.nextInt();
m=scanner.nextInt();
if(n+m==0){
break;
}
scanner.nextLine();
for(int i=0;i<n;i++){
String str=scanner.nextLine();
char a[]=str.toCharArray();
for(int j=0;j<m;j++){
map[i][j]=a[j];
}
}
int sum=0;
init();
for(int i=0;i<n;i++){
for(int j=0;j<m;j++){
if(!vis[i][j]&&map[i][j]=='@'){//当从每个点出发搜索的时候 都会标记以改点扩散的油田 当从下个点搜索的时候
sum++;//就直接不搜索改点
dfs(i,j);
}
}
}
System.out.println(sum);
}
}
private static void dfs(int x, int y) {
vis[x][y]=true;
for(int i=0;i<8;i++){
int dx=x+dir[i][0];
int dy=y+dir[i][1];
if(dx>=0&&dx<n&&dy>0&&dy<m&&!vis[dx][dy]&&map[dx][dy]=='@'){
dfs(dx,dy);
}
}
}
private static void init() {
for(int i=0;i<MAX_N;i++){
for (int j=0;j<MAX_N;j++){
vis[i][j]=false;
}
}
}
}
相关文章推荐
- java-正则表达式判断移动联通电信手机号
- java实现基于SGIP协议开发联通短信的方法
- 图方法:寻找无向图联通子集的JAVA版本
- JAVA设计模式学习第四天 设计模式之Mediator——联通篇
- 【Redis缓存机制】11.Java连接Redis_Jedis_测试联通
- Java_IO流_“联通” “学习” 的编码问题
- java工程师联通XX面试题目
- java中文件的编码(在建立text文本时,如果文件中只写联通或是联,再次打开的时候就会出现乱码,下面就是原理)
- 联通SGIP1.2短信接口 Java版实现 总结 2013-10-23测试通过
- java检查服务器的联通
- 用Java解析手机号获取手机信息(归属地、Sim卡类型、移动或是联通、区号、邮编)
- java实现移动,联通,电信手机号码的验证
- java代码测试网络是否联通
- java实现基于SGIP协议开发联通短信的方法
- java之 21天 (三)"联通" 乱码 和 IO练习
- Java实现WinPcap+Wireshark数据抓包模拟联通客户端签到功能
- java 验证手机号码、电话号码(包括最新的电信、联通和移动号码)
- java输出'联通'记事本的那些乱码
- java 验证手机号码、电话号码(包括最新的电信、联通和移动号码)
- HDU1241 求联通块个数(DFS)