地址:http://poj.org/problem?id=1164
问题描述:图1是一个城堡的地形图。请你编写一个程序,计算
城堡一共有多少房间
最大的房间有多大
城堡被分割成m´n(m≤50,n≤50)个方块,每个方块可以有0~4面墙
输入:程序从标准输入设备读入数据。
第一行是两个整数,分别是南北向、东西向的方块数。
在接下来的输入行里,每个方块用一个数字(0≤p≤50)描述。用一个数字表示方块周围的墙,1表示西墙,2表示北墙,4表示东墙,8表示南墙。
每个方块用代表其周围墙的数字之和表示。城堡的内墙被计算两次,方块(1,1)的南墙同时也是方块(2,1)的北墙。
输入的数据保证城堡至少有两个房间
输出:城堡的房间数、城堡中最大房间所包括的方块数。结果显示在标准输出设备上。
思路1:
对任意的方块(i,j),在输入描述中用p表示
p<8
p (i,j)没有南墙,(i+1,j)与(i,j)属于同一房间
p所有与(i+1,j) 属于同一房间的方块也与(i,j)属于同一房间
p%8<4
p (i,j)没有东墙, (i,j+1)与(i,j)属于同一房间
p所有与(i,j+1)属于同一房间的方块也与(i,j)属于同一房间
p%4<2
p(i,j) 没有北墙 ,(i-1,j)与(i,j)属于同一房间
p所有与(i-1,j)属于同一房间的方块也与(i,j)属于同一房间
p%2=0
p (i,j)没有西墙,(i,j-1)与(i,j)属于同一房间
p所有与(i,j-1)属于同一房间的方块也与(i,j)属于同一房间
题目求: 房间的个数 和 房间的最大面积。
思路2:为了调试看起来方便,用8表示墙,用0表示通路(当然房间区域也是可以走通的,所以也用0表示),用(2*row+1)*(2*column+1)的矩阵来表示(0 ≤ i ≤ 2*row ,0 ≤ j ≤ 2*column),当 i,j 都为奇数时,点(i , j)表示房间区域, 其余则为墙或门。
心得:原先没有想到还有这种情况:
3 3
3 2 6
1 0 4
9 8 12
经过调试发现,房间区域为8了,但路上还是0,这样就会引起重复计算,对dfs()做了修改:
while()里加了这句 room[i][j] == '0');
把这句 len++; 提到最前。
1 代码 2 3 #include<stdio.h> 4 #include<string.h> 5 6 int row, column, len; 7 char room[101][101]; 8 9 void dfs(int i, int j) 10 { 11 while(i>=1 && i<=(row<<1) && j>=1 && j<=(column<<1) && room[i][j] == '0') 12 { 13 len++; 14 room[i][j] = '8'; 15 if(room[i][j+1] == '0') 16 { 17 room[i][j+1] = '8'; 18 dfs(i, j+2); 19 } 20 if(room[i+1][j] == '0') 21 { 22 room[i+1][j] = '8'; 23 dfs(i+2, j); 24 } 25 if(room[i][j-1] == '0') 26 { 27 room[i][j-1] = '8'; 28 dfs(i, j-2); 29 } 30 if(room[i-1][j] == '0') 31 { 32 room[i-1][j] = '8'; 33 dfs(i-2, j); 34 } 35 } 36 } 37 38 int main() 39 { 40 int i, j, nRoom, max, num; 41 while(scanf("%d %d", &row, &column) != EOF) 42 { 43 for(i=0; i<=(row<<1); i++) //初始化 44 for(j=0; j<=(column<<1); j++) 45 room[i][j] = '8'; //8为墙,0为路 46 47 for(i=1; i<=(row<<1); i+=2) //铺房间 48 for(j=1; j<=(column<<1); j+=2) 49 { 50 scanf("%d", &num); 51 room[i][j] = '0'; 52 if(!(num&1) && room[i][j-1] == '8') room[i][j-1] = '0'; 53 if(!(num&2) && room[i-1][j] == '8') room[i-1][j] = '0'; 54 if(!(num&4) && room[i][j+1] == '8') room[i][j+1] = '0'; 55 if(!(num&8) && room[i+1][j] == '8') room[i+1][j] = '0'; 56 } 57 58 max = 0; 59 nRoom = 0; 60 for(i=1; i<=(row<<1); i+=2) 61 for(j=1; j<=(column<<1); j+=2) 62 if(room[i][j] == '0') 63 { 64 nRoom++; 65 len = 0; 66 dfs(i, j); 67 if(len > max) max = len; 68 } 69 70 printf("%d\n%d\n", nRoom, max); 71 } 72 return 0; 73 }
转载:
1 //POJ1164 2 //DFS standard , pay attention to the way to indicate the walls, 3 //整个遍历过程,搜索一个“块“在函数内进行,不同块的连续在主函数内处理。此题中无需改回标记 4 #include<iostream> 5 #include<cstdio> 6 #include<string> 7 #include<cstdlib> 8 #include<cstring> 9 #define N 60 10 using namespace std; 11 bool map[N][N]; 12 int castle[N][N]; 13 int room=0;//房间数 14 int step,p,q;//step为搜索时走的步数,即当前房间的面积 15 bool inmap(int x,int y){//judge if the point is in the map 16 return ( x<=p && y<=q && x>0 && y>0 ); 17 } 18 void search(int x,int y){//search from (x,y) 19 step++; 20 map[x][y] = true; 21 22 int temp = castle[x][y]; 23 if (temp < 8){//do not have the south wall 24 if( inmap(x+1,y) && !map[x+1][y] ) 25 search(x+1,y); 26 } 27 else temp -= 8; 28 29 if (temp < 4){//do not have the east wall 30 if( inmap(x,y+1) && !map[x][y+1] ) 31 search(x,y+1); 32 } 33 else temp -= 4; 34 35 if (temp < 2){//do not have the north wall 36 if( inmap(x-1,y) && !map[x-1][y] ) 37 search(x-1,y); 38 } 39 else temp -= 2; 40 41 if (temp < 1){//do not have the west wall 42 if( inmap(x,y-1) && !map[x][y-1] ) 43 search(x,y-1); 44 } 45 } 46 int main(){ 47 cin >> p >> q; 48 //input 49 for(int i=1;i<=p;i++) 50 for(int j=1;j<=q;j++) 51 cin >> castle[i][j]; 52 //init 53 memset(map,false,sizeof(map)); 54 //search 55 int lar = 0; 56 for(int i=1;i<=p;i++) 57 for(int j=1;j<=q;j++){ 58 if( !map[i][j] ){ 59 step = 0; 60 search(i,j); 61 room++; 62 if(lar < step )//find the largest room 63 lar = step; 64 } 65 } 66 //output 67 cout << room <<endl; 68 cout << lar << endl; 69 return 0; 70 }