#广搜#洛谷 1457 codevs 3102 the castle 城堡

前言

一开始就不会的先看这个(https://blog.csdn.net/sugar_free_mint/article/details/78756925)


题目

还要求推倒墙后形成的房间面积最大,求面积和墙的位置。


分析

广搜,具体看代码!(不结合代码讲不出来)


代码

/*
ID:lemond1
LANG:C++
TASK:castle
*/
#include <cstdio>
#include <algorithm>
using namespace std;
const int dx[4]={0,0,-1,1},dy[4]={1,-1,0,0}; int x,y; char ch;
enum way{W,E,S,N};int n,m,big,ans;bool a[51][51][4]; int d,v[51][51],f[2501];
bool check(int x,int y,int i){
    if (x<1||x>n||y<1||y>m||v[x][y]||a[x][y][i]) return false; else return true;
}
int bfs(int x,int y){
    int head=0,tail=1,stat[2501][2]; v[x][y]=ans,stat[1][0]=x,stat[1][1]=y;
    do{
        head++; 
        for (int i=0;i<4;i++)
        if (check(stat[head][0]+dx[i],stat[head][1]+dy[i],i))
        {tail++;
                 v[stat[head][0]+dx[i]][stat[head][1]+dy[i]]=ans;
                 stat[tail][0]=stat[head][0]+dx[i];
                 stat[tail][1]=stat[head][1]+dy[i];
                 }
    }while (head<tail); return tail;
}
int main(){
    freopen("castle.in","r",stdin);
    freopen("castle.out","w",stdout);
    scanf("%d%d",&m,&n);
    for (int i=1;i<=n;i++)
    for (int j=1;j<=m;j++){
        scanf("%d",&d);
        if (d>=8) a[i][j][S]=1,d-=8;
        if (d>=4) a[i][j][E]=1,d-=4; 
        if (d>=2) a[i][j][N]=1,d-=2;
        if (d==1) a[i][j][W]=1,d-=1; 
    }
    for (int i=1;i<=n;i++)
    for (int j=1;j<=m;j++)
	if (!v[i][j]) big=max((f[++ans]=bfs(i,j)),big);//f表示房间面积(广搜)
    printf("%d\n%d\n",ans,big);
    for (int j=1;j<=m;j++)//优先选择西面的房间
    for (int i=n;i>=1;i--){//再选择南面的房间
	if (a[i][j][N]&&v[i][j]!=v[i-1][j]&&(big<f[v[i][j]]+f[v[i-1][j]]||big==f[v[i][j]]+f[v[i-1][j]&&!x&&!y]))//当找到最大的房间或找到相等的房间并没有算过答案
	big=f[v[i][j]]+f[v[i-1][j]],x=i,y=j,ch='N';//靠北的墙优先
	if (a[i][j][E]&&v[i][j]!=v[i][j+1]&&(big<f[v[i][j]]+f[v[i][j+1]]||big==f[v[i][j]]+f[v[i][j+1]]&&!x&&!y)) //the same
	big=f[v[i][j]]+f[v[i][j+1]],x=i,y=j,ch='E';}
	return !printf("%d\n%d %d %c",big,x,y,ch);
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值