POJ1164 + USACO Section 2.1 The Castle - 简单的DFS...

    两个题是一个题~~只不过POJ的更弱些,只要找到房间数以及最大房间的面积就ok了...

    首先是构造墙~~我是用个4位的bool数组来记录每个点的墙的情况...读入时就%2.再/2...就可以构造出来~~

    找房间数和最大房间直接DFS就可以了~~边遍历边标记~~每个点标记成所在的区域~~在递归的过程中很好实现~

    而找去掉一面墙以及去掉一面墙最大面积~~就按所要求的优先顺序枚举墙~~判断下两边是否为一个房间~~并且两边的和是否是最大的~~~


Program:

/*   
ID: zzyzzy12   
LANG: C++   
TASK: castle 
*/      
#include<iostream>      
#include<stdio.h>      
#include<string.h>      
#include<math.h>      
#include<algorithm>      
#include<queue>  
using namespace std;     
struct node  
{  
     bool s[4];     
     int data;     
}mar[55][55];  
int n,m,i,j,k,t,Size[3001],MaxSize,RoomNum,ans,x,y;  
char f;  
void search(int y,int x)  
{  
     if (mar[y][x].data) return;  
     Size[RoomNum]++;  
     mar[y][x].data=RoomNum;  
     if (!mar[y][x].s[0]) search(y,x-1);      
     if (!mar[y][x].s[1]) search(y-1,x);   
     if (!mar[y][x].s[2]) search(y,x+1);   
     if (!mar[y][x].s[3]) search(y+1,x);   
}  
int main()  
{  
     freopen("castle.in","r",stdin);  
     freopen("castle.out","w",stdout);    
     scanf("%d%d",&m,&n);  
     memset(mar,0,sizeof(mar));  
     for (i=1;i<=n;i++)  
        for (j=1;j<=m;j++)  
        {  
              scanf("%d",&k);  
              t=0;  
              while (k)  
              {  
                    if (k%2) mar[i][j].s[t]=true;  
                    k/=2;  
                    t++;  
              }   
        }    
     MaxSize=RoomNum=0;  
     for (i=1;i<=n;i++)  
        for (j=1;j<=m;j++)  
        if (!mar[i][j].data)  
        {    
              RoomNum++;  
              Size[RoomNum]=0;  
              search(i,j);  
              if (Size[RoomNum]>MaxSize) MaxSize=Size[RoomNum];                      
        }  
     printf("%d\n%d\n",RoomNum,MaxSize);  
     ans=0;  
     for (j=1;j<=m;j++)  
        for (i=n;i>=1;i--)  
        {  
              if (mar[i][j].s[0] && j!=1 && mar[i][j].data!=mar[i][j-1].data && ans<Size[mar[i][j].data]+Size[mar[i][j-1].data])   
              {  
                    y=i;  x=j; f='W';  ans=Size[mar[i][j].data]+Size[mar[i][j-1].data];                  
              }    
              if (mar[i][j].s[1] && i!=1 && mar[i][j].data!=mar[i-1][j].data && ans<Size[mar[i][j].data]+Size[mar[i-1][j].data])   
              {  
                    y=i;  x=j; f='N';  ans=Size[mar[i][j].data]+Size[mar[i-1][j].data];                  
              }    
              if (mar[i][j].s[2] && j!=m && mar[i][j].data!=mar[i][j+1].data && ans<Size[mar[i][j].data]+Size[mar[i][j+1].data])   
              {  
                    y=i;  x=j; f='E';  ans=Size[mar[i][j].data]+Size[mar[i][j+1].data];                
              }    
              if (mar[i][j].s[3] && i!=n && mar[i][j].data!=mar[i+1][j].data && ans<Size[mar[i][j].data]+Size[mar[i+1][j].data])   
              {  
                    y=i;  x=j; f='S';  ans=Size[mar[i][j].data]+Size[mar[i+1][j].data];                  
              }        
        }   
     printf("%d\n%d %d %c\n",ans,y,x,f);
     return 0;     
}  


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值