[2016/7/11][usaco 2.1][Flood Fill][dfs] The Castle

来源:互联网 发布:sql挂起清除 编辑:程序博客网 时间:2024/05/23 01:20

http://train.usaco.org/usacoprob2?a=ZSn5SwI7CNy&S=castle

题目大意:给个m*n的图,每个格子里是数字,代表四个方向有没有墙。求有几个房间,最大房间面积,拆掉某墙后最大房间面积,拆掉哪座墙。


简直太坑。。写了一天最后发现最关键的34问思路有问题,于是看了看别人的解题报告,把所有代码删了重写。

重写之后的代码短了一半。。

关键点:拆掉某墙之后最大房间面积。此时只需要遍历所有墙。也不算慢,直接比较拆后和当前最大谁大。这一步也可以解决拆哪座墙的问题。

之前的思路错在:先判断房间之间是否相邻,再算合并面积。这样只能有效解决3,而且浪费空间,多开个数组记录是否相邻。而且,如果有两个房间加起来面积一样大,就很难解决4的问题。

还是得学会用计算机的思维解决问题qwq

代码:

/*PROG:   castleID  :   49743541LANG:   C++*/#include <stdio.h>#include <vector>#include <algorithm>#include <math.h>using namespace std;typedef struct{bool dong;bool xi;bool nan;bool bei;}room;int map[52][52];int color[52][52];room r[52][52];int amount[2504];//不同颜色房间的大小 int c;int row,column;void wall(int i,int j){//判断这个格子的四个方向有没有墙if(map[i][j]&1) r[i][j].xi = 1;if(map[i][j]&2) r[i][j].bei = 1;if(map[i][j]&4) r[i][j].dong = 1;if(map[i][j]&8) r[i][j].nan = 1;//printf("%d %d %d %d\n",r[i][j].dong,r[i][j].nan,r[i][j].xi,r[i][j].bei);return;}void Floodfill(int i,int j){ //if(color[i][j])//不用判断越界,因为边界一定有墙,搜不出去return;color[i][j] = c;amount[c]++;//统计数目 if(!r[i][j].xi) Floodfill(i,j-1);if(!r[i][j].bei) Floodfill(i-1,j);if(!r[i][j].dong) Floodfill(i,j+1);if(!r[i][j].nan) Floodfill(i+1,j);return; }int main(){freopen("castle.in", "r", stdin);   freopen("castle.out", "w", stdout);scanf("%d%d",&column,&row);for(int i = 0;i<row;i++)for(int j = 0;j<column;j++){scanf("%d",&map[i][j]);wall(i,j);//判断房间周围的墙}for(int i = 0;i<row;i++)for(int j = 0;j<column;j++){if(!color[i][j]){c++;Floodfill(i,j);}}printf("%d\n",c);//房间数量int maxarea = 0;for(int i = 1;i<=c;i++)maxarea = max(maxarea,amount[i]);//遍历,找出最大房间面积printf("%d\n",maxarea);int maxcarea = 0;int x = 0;int y = 0;//满足条件的格子坐标char c;//满足条件的墙方向int ca,cb;for(int i = 0;i<row;i++)for(int j = 0;j<column;j++){//因为题目只说了两个方向,所以只用考虑两个方向ca = color[i][j];if(i>=0 && j+1<=column-1 && color[i][j]!=color[i][j+1] && r[i][j].dong){//注意优先级!!cb = color[i][j+1];if(maxcarea<amount[ca]+amount[cb]){maxcarea = amount[ca]+amount[cb];x = i;y = j;c = 'E';}else if(maxcarea==amount[ca]+amount[cb]){if(j<y){y = j;x = i;c = 'E';}if(j==y){if(i>x){x = i;c = 'E';}}}}if(i-1>=0 && j>=0 && color[i][j]!=color[i-1][j] && r[i][j].bei){cb = color[i-1][j];if(maxcarea<amount[ca]+amount[cb]){maxcarea = amount[ca]+amount[cb];x = i;y = j;c = 'N';}else if(maxcarea==amount[ca]+amount[cb]){if(j<y){y = j;x = i;c = 'N';}if(j==y){if(i>x)x = i;if(i==x)c = 'N';}}  }}printf("%d\n",maxcarea);printf("%d %d %c\n",x+1,y+1,c);/*for(int i = 0;i<row;i++){printf("\n");for(int j = 0;j<column;j++){printf("%d ",color[i][j]);}}*///printf("%d",amount[2]);return 0;} 




0 0
原创粉丝点击