杭电1045 fire net dfs入门

13 篇文章 0 订阅

题意是有n*n大小的地图,地图上点(.)代表空地,X代表防火墙,在地图上放置碉堡,碉堡可以横向或者竖向扫射,所以同一行或列上只能有一个碉堡,但是防火墙可以阻拦攻击,求最大能放置多少碉堡

// HDOJ1042 fire net
// 思维是主要靠深搜

#include <iostream>
using namespace std;
int visit[5][5];    // visit数组是用来存放状态的,0代表空地,1代表放了碉堡,2代表防火墙
int mmax, n, cnt;
bool ffind(int x, int y);   // 判断当前位置是否可以放碉堡
void dfs();

int main()
{
    char str[10];
    while(cin >> n && n)
    {
        for(int i = 1; i <= n; i++)
        {
            cin >> str;
            for(int j = 0; j < n; j++)
                visit[i][j + 1] = (str[j] == 'X' ? 2 : 0);
        }
        cnt = mmax = 0;
        dfs();
        cout << mmax << endl;
    }

    return 0;
}

bool ffind(int x, int y)
{
    // 从(x, y)点开始上下左右判断,如果遇到碉堡就返回false,如果遇到墙就结束本次循环
    for(int i = y; i >= 1; i--)
    {
        if(visit[x][i] == 1)
            return false;
        if(visit[x][i] == 2)
            break;
    }
    for(int i = y; i <= n; i++)
    {
        if(visit[x][i] == 1)
            return false;
        if(visit[x][i] == 2)
            break;
    }
    for(int i = x; i >= 1; i--)
    {
        if(visit[i][y] == 1)
            return false;
        if(visit[i][y] == 2)
            break;
    }
    for(int i = x; i <= n; i++)
    {
        if(visit[i][y] == 1)
            return false;
        if(visit[i][y] == 2)
            break;
    }

    return true;
}

void dfs()
{
    // 一列一列的深搜,如果发现一点能放碉堡就令状态数组变为1,表示放置碉堡
    // 然后继续往下搜索,放置一个碉堡就领cnt计数器自增
    // 如果搜索完整个,就跳出本次循环,将碉堡重新设置为空地
    if(cnt > mmax)
        mmax = cnt;
    for(int i = 1; i <= n; i++)
        for(int j = 1; j <= n; j++)
            if(!visit[i][j] && ffind(i,j))
            {
                visit[i][j] = 1;
                cnt++;
                // cout << "in" << endl;    // 测试用
                dfs();
                // cout << "out" << endl;   // 测试用
                visit[i][j] = 0;
                cnt--;
            }
}
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值