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; }

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值