(DFS)城堡问题

题目

在这里插入图片描述

   # = Wall  
   |  = No wall
   -  = No wall

图1是一个城堡的地形图。请你编写一个程序,计算城堡一共有多少房间,最大的房间有多大。城堡被分割成mn(m≤50,n≤50)个方块,每个方块可以有0~4面墙。       

input

程序从标准输入设备读入数据。第一行是两个整数,分别是南北向、东西向的方块数。在接下来的输入行里,每个方块用一个数字(0≤p≤50)描述。用一个数字表示方块周围的墙,1表示西墙,2表示北墙,4表示东墙,8表示南墙。每个方块用代表其周围墙的数字之和表示。城堡的内墙被计算两次,方块(1,1)的南墙同时也是方块(2,1)的北墙。输入的数据保证城堡至少有两个房间。

output

城堡的房间数、城堡中最大房间所包括的方块数。结果显示在标准输出设备上。

样例

4
7
11 6 11 6 3 10 6
7 9 6 13 5 15 5
1 10 12 7 13 7 5
13 11 10 8 10 12 13

输出

5
9
给一个数,要看有几面墙
0001
0010
0100
1000

例如13就要131进行与操作,判断他第几位为1,就是他有什么墙

深度优先搜索问题就是图的问题
我们要有一个建模的思想


解题思路
把方块看作是节点,相邻两个方块之间如果没有墙,则在方块之间连一条边,这样城堡就能转换成一个图

求房间个数,实际上就是图中有多少个极大联通子图


例如 2,4,9  5,6,8
极大联通子图:再往里面加一个东西就不联通了
例如 5,6,8,

对每个房间,深度优先搜索,从而给这个房间能够到达的所有位置染色。最后统计一个用了几种颜色,以及每种颜色的数量

在这里插入图片描述


#include<cstdio>
#include<cstring>
#include<iostream>
INT R,C;//行列数,R行C列
int rooms[60][60];//把城堡的房间存起来,存放整个城堡的方块,romms[i][j]表示第i行第j列的方块所对应的数字,对应这个墙的情况
int color[60][60];//方块是否染色过的标记,就是说走没走过
int maxRoomArea =0,roomNum=0;//表示最大房间面积,和已经找到房间的数目
int roomArea;//我正在探索的房间的面积
//深度优先搜索的过程
void Dfs(int i,int k){//进行探索
	if(color[i][k])//如果访问过这个点
		return;//不能再走
	++ roomArea;//如果没访问过,房间的面积+1,就是说又加了一个节点
	color[i][k]=roomNum;//访问过的路径此时这点就被记为房间的大小
	if((rooms[i][k]&1)==0) Dfs(i,k-1);//向西走,西0001
	if((rooms[i][k]&2)==0) Dfs(i-1,k);//向北走,北0010
	if((rooms[i][k]&4)==0) Dfs(i,k+1);//向东走,东0100
	if((rooms[i][k]&8)==0) Dfs(i+1,k);//向南走,南1000
	
}
int main(){
	cin>>R>>C;//读取R,C,相当于java里面的Scanner
	//把每个方块所对应的数给读进来
	for(int i=1;i<=R;i++)
	for(int k=1;k<=C;k++)
	cin>>rooms[i][k];
	//用memset把color数组全部置位0,所有的方块都没有走过
	memset(color,0,sizeof(color);
	//深度优先进行遍历的做法
	//通过循环去找新点
	//通过两重循环,找到第i行第k行的数组是否被染色
	for(int i=1;i<=R;i++)
		for(int k=1;k<=C;k++){
		//没有被走过
		//探索一个房间,找到一个极大联通子图,回到两重循环,之后再找到一个新的联通子图
			if(!color[i][k]){
			//新的房间的起点,当发现方块没有走过,找到新的房间
			//探索这个房间,这个房间的面积为0;
				++ roomNum; roomArea=0;
				//把这个房间走过的方块,全部包围染色了的
				//找到了没有走过的方块就说明找到了另一个房间
				Dfs(i,k);
				//Dfs执行完了之后,就说明面积也被求完了,探索完了之后,作比较,并更新
				maxRoomArea=max(roomArea,maxRoomArea);
			}
		}

	cout<<roomNum<<end1;//输出房间数
	cout<<maxROOMaREA<<endl;//输出最大面积
}




java实现

package DFS;

import java.util.Arrays;
import java.util.Scanner;

public class 城堡问题 {
	static int R,C;
	static int[][] rooms;
	static int[][] color;
	static int maxRoomArea=0,roomNum=0;
	static int roomArea;
	
	public static void main(String[] args) {
		// TODO Auto-generated method stub
		Scanner sc=new Scanner(System.in);
		R=sc.nextInt();
		C=sc.nextInt();
		int rooms[][]=new int[R+2][C+2];
		int color[][]=new int[R+2][C+2];
		for(int i=1;i<=R;i++){
			for(int j=1;j<=C;j++){
				rooms[i][j]=sc.nextInt();
			}
		}
		for(int i=0;i<=R;i++){
			for(int j=0;j<=C;j++){
				color[i][j]=0;
			}
		}
		
		for(int i=1;i<=R;i++){
			for(int j=1;j<=C;j++){
				if(color[i][j]==0){
					roomNum++;
					roomArea=0;
					Dfs(i,j,rooms,color);
					maxRoomArea=Math.max(roomArea,maxRoomArea);
				}
			}
		}
		System.out.println(roomNum);
		System.out.println(maxRoomArea);
	}

	private static void Dfs(int i, int j,int[][] rooms,int[][] color) {
		// TODO Auto-generated method stub
		if(i==0||i==(R+1)||j==0||j==(C+1)){
			return;
		}
		if(color[i][j]==0){
		roomArea++;
		color[i][j]=roomNum;//访问过的路径此时这个房间的大小
		if((rooms[i][j]&1)==0) Dfs(i,j-1,rooms,color);//向西走,西0001
		if((rooms[i][j]&2)==0) Dfs(i-1,j,rooms,color);//向北走,北0010
		if((rooms[i][j]&4)==0) Dfs(i,j+1,rooms,color);//向东走,东0100
		if((rooms[i][j]&8)==0) Dfs(i+1,j,rooms,color);//向南走,南1000
		}
	}

}

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

向上Claire

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值