【问题描述】
给你一块n*m的草坪,问如果只点一次火,最多能烧多少块草坪。可以从n*m的草地中任意一个地方开始点火,火只能往上下左右传递,没有草的地方不能燃烧。
【输入格式】
输入由多个测试例组成。每个测试例的第一行含两个整数n和m, (1 <=n,m<=100), 分别表示01矩阵的行数与列数,
后面紧跟着n行,每行含m个整数0或1,1代表草坪,0表示啥也没有,相邻两个整数之间用一个空格隔开,两个测
试例之间用一个空行隔开,最后一个测试例之后隔一个空行,最后一行含有两个整数0,表示输入结束。
【输出格式】
每个测试例对应一行输出,含一个整数,表示只点一次火最多能烧的草坪个数。
【样例输入】
5 6
0 1 1 0 0 1
1 1 0 1 0 1
0 1 0 0 1 0
0 0 0 1 1 1
1 0 1 1 1 0
0 0
【样例输出】
7
该题可以跟连通块结合
核心代码:
首先草坪想要烧起来,只能上下左右烧,并且得判断是否是1,是1才能烧起来。所以设置四个方向的遍历,采用了数组的方式。
int f[4][2]= {{0,1},{0,-1},{1,0},{-1,0}};
草坪每烧一个采用计数变量计数,并且下一个草坪也会进行一个上下左右的方向,因此便是四个方向的深度遍历,并且需要对草坪进行判断,防止越界,以及判断草坪为1。
for(int i=0; i<4; i++) {
int dx = x+f[i][0];
int dy = y+f[i][1];
if(dx>=0 && dy>=0 && dx<m && dy<n && a[dx][dy]==1) {
a[dx][dy]=0;
dfs(dx,dy);
}
}
优化代码:
public class Test3 {
static int a[][]=new int[100][100];
//方向数组上下左右
static int f[][]= {{0,1},{0,-1},{1,0},{-1,0}};
//标志数用于记录个数
static int max=0;
static int n;
static int m;
static int cout=1;
static void dfs(int x,int y){
a[x][y]=0;
//对四个方向的深度遍历
for(int i=0; i<4; i++) {
int dx = x+f[i][0];
int dy = y+f[i][1];
//防止越界,以及对1的草坪进行点火
if(dx>=0 && dy>=0 && dx<m && dy<n && a[dx][dy]==1) {
a[dx][dy]=0;
dfs(dx,dy);
cout++;
}
}
}
public static void main(String [] args){
Scanner scan = new Scanner(System.in);
m= scan.nextInt();
n= scan.nextInt();
//对数组赋值0,1
for (int i=0;i<m;i++) {
for (int j = 0; j < n; j++) {
a[i][j] = scan.nextInt();
}
}
//遍历找到1的草坪点火,0的略过
for (int i=0;i<m;i++) {
for (int j = 0; j < n; j++) {
if(a[i][j]==1) {
dfs(i, j);
max=max>cout?max:cout;
cout=1;
}
}
}
System.out.println(max);
}
}