原文链接:http://poj.org/problem?id=1164
每个小格1*1都有四个面,东西南北,如图*代表在该小格该面有wall;至于输入设置,例如11=1+2+8,意味着(0,0)这个格的W、N和S方向有wall。 我的代码:
#include <stdio.h> struct{ int E; int S; int W; int N; int flag; } map[50][50]; //地图,有E、S、W、N顺序的四个方向,flag作为是否走过的标记 int n,m,max,sum;//max为最大房间的格数 void DFS(int i,int j){ if(sum>max) max=sum; if(!map[i][j].flag){ if(!map[i][j].E){ map[i][j].flag=1; if(!map[i][j+1].flag){ sum++; DFS(i,j+1); } } if(!map[i][j].S){ map[i][j].flag=1; if(!map[i+1][j].flag){ sum++; DFS(i+1,j); } } if(!map[i][j].W){ map[i][j].flag=1; if(!map[i][j-1].flag){ sum++; DFS(i,j-1); } } if(!map[i][j].N){ map[i][j].flag=1; if(!map[i-1][j].flag){ sum++; DFS(i-1,j); } } } else return ; } int main(){ int i,j,num=0,date,num1=0; scanf("%d%d",&n,&m);//m列n行 for(i=0; i<n; i++){ for(j=0; j<m; j++){ scanf("%d",&date); //以下四个if用来将1、2、4、8转换为四个方向有无wall的0、1值 if(date%2){ map[i][j].W=1; date--; } if(!(date<8)){ map[i][j].S=1; date-=8; } if(!(date<4)){ map[i][j].E=1; date-=4; } if(date==2) map[i][j].N=1; } }//这两个for循环套用只是为了上一次房间格数找到后,重新寻找未被标记的房间 for(i=0; i<n; i++){ for(j=0; j<m; j++){ if(!map[i][j].flag){ sum=1; DFS(i,j); num++; num1+=max; } } if(num1==n*m)//nun1累加每次找的的房间格数,当找到n*m个格数可直接break,即所谓的剪枝 break; } printf("%d\n%d\n",num,max); return 0; }