城堡问题

来源:互联网 发布:android 循环网络请求 编辑:程序博客网 时间:2024/04/29 00:13
/*1164:The Castle总时间限制: 1000ms 内存限制: 65536kB描述     1   2   3   4   5   6   7     ############################# 1 #   |   #   |   #   |   |   #   #####---#####---#---#####---# 2 #   #   |   #   #   #   #   #   #---#####---#####---#####---# 3 #   |   |   #   #   #   #   #   #---#########---#####---#---# 4 #   #   |   |   |   |   #   #   #############################(Figure 1)#  = Wall   |  = No wall-  = No wallFigure 1 shows the map of a castle.Write a program that calculates1. how many rooms the castle has2. how big the largest room isThe castle is divided into m * n (m<=50, n<=50) square modules. Each such module can have between zero and four walls. 输入Your program is to read from standard input. The first line contains the number of modules in the north-south direction and the number of modules in the east-west direction. In the following lines each module is described by a number (0 <= p <= 15). This number is the sum of: 1 (= wall to the west), 2 (= wall to the north), 4 (= wall to the east), 8 (= wall to the south). Inner walls are defined twice; a wall to the south in module 1,1 is also indicated as a wall to the north in module 2,1. The castle always has at least two rooms.输出Your program is to write to standard output: First the number of rooms, then the area of the largest room (counted in modules).样例输入4711 6 11 6 3 10 67 9 6 13 5 15 51 10 12 7 13 7 513 11 10 8 10 12 13样例输出59来源IOI 1994解题总结:本题主要思路就是从每一个点的四个方向开始搜索,如果可以走通的话就将该处的位置标记为与之具有相同标号一个搜索完毕后,就令编号加一因为墙是用1,2,4,8记录的,很容易让人联想到通过按位与来测量该点的各个方向是否有墙搜索完毕后,即得房间数,再遍历标记,找出最大的房间号编写过程中失误的地方:1.memset(room,0,sizeof(CurId)),CurId是指针,而非数组名,sizeof(CurId) = 4 而非数组字节数,应为memset(room,0,sizeof(int)*CurId);2.编写mark函数时,对于x,y到底是指那个方向时没有弄清楚,导致搜索方向错误3.判断边界条件时,除了x,y不超过边界时,如果已标记,就不用再标记了  关键是已标记并不是Mark[x][y] == 1而应该是Mark[x][y] != 0,否则就导致了循环标记,陷入死循环*/#include<iostream>#include<cstring>using namespace std;int r,c;int **Data,**Mark;void mark(int x,int y,int Id){if(x < 0 || x >= r || y < 0 || y >= c || Mark[x][y] != 0)return;Mark[x][y] = Id;//巧用按位与,==0则表示该方向没有墙,进入搜索if((Data[x][y] & 0x01) == 0)//search westmark(x,y-1,Id);if((Data[x][y] & 0x02) == 0) //search northmark(x-1,y,Id);if((Data[x][y] & 0x04) == 0) //search eastmark(x,y+1,Id);if((Data[x][y] & 0x08) == 0) //search southmark(x+1,y,Id);}void Work(){cin >> r >> c;int i,j,CurId = 1;Data = new int* [r];Mark = new int* [r];for(i = 0; i < r; ++i){Data[i] = new int [c];Mark[i] = new int [c];for(j = 0; j < c; ++j)cin >> Data[i][j];memset(Mark[i],0,sizeof(int)*c);}for(i = 0; i < r; ++i)//开始深度搜索,调用mark函数for(j = 0; j < c; ++j){if(Mark[i][j] == 0){mark(i,j,CurId);++CurId;}}//遍历寻找最大的房间,和总共的房间数int rMax = -1,*room;room = new int [CurId];memset(room,0,sizeof(int)*CurId);for(i = 0; i < r; ++i)for(j = 0; j < c; ++j)++room[Mark[i][j]];for(i = 0; i < CurId; ++i)if(rMax < room[i])rMax = room[i];cout << CurId - 1 << endl << rMax << endl;//释放内存空间for(i = 0; i < r; ++i){delete Mark[i];delete Data[i];}delete [] room;delete [] Data;delete [] Mark;}int main(){Work();return 0;}

0 0
原创粉丝点击