炸弹袭击 - LintCode

该博客讨论了一个二维矩阵问题,其中矩阵的每个单元格可能是墙、敌人或空地。目标是确定在给定条件下,放置一枚炸弹能消灭的最大敌人数量。炸弹可以消灭同一行和同一列中没有被墙阻挡的所有敌人。解决方案涉及计算四个主要方向上的敌人数量,并返回最高值。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

描述
给一个二维矩阵, 每一个格子都可能是一堵墙 W, 一个敌人 E 或者空 0 (数字 ‘0’), 返回你可以用一个炸弹杀死的最大敌人数. 炸弹会杀死所有在同一行和同一列没有墙阻隔的敌人, 因为墙比较坚固难以摧毁.

你只能在空的地方放置炸弹.

样例
给一个矩阵:

0 E 0 0
E 0 W E
0 E 0 0

返回 3.(在(1, 1)处放炸弹可以杀死 3 个敌人)

思路
分别计算四个方向的杀死敌人的数目,最终返回最大值。

#ifndef C553_H
#define C553_H
#include<iostream>
#include<vector>
#include<string>
#include<algorithm>
using namespace std;
class Solution {
public:
    /**
    * @param grid: Given a 2D grid, each cell is either 'W', 'E' or '0'
    * @return: an integer, the maximum enemies you can kill using one bomb
    */
    int maxKilledEnemies(vector<vector<char>> &grid) {
        // write your code here
        if (grid.empty() || grid[0].empty())
            return 0;
        int rows = grid.size();
        int cols = grid[0].size();
        //up[i][j],down[i][j],left[i][j],right[i][j]分别表示grid[i-1][j-1]上下左右四个方向上可以杀死的敌人数
        vector<vector<int>> 
            left(rows + 2, vector<int>(cols + 2, 0)),
            right(rows + 2, vector<int>(cols + 2, 0)),
            up(rows + 2, vector<int>(cols + 2, 0)),
            down(rows + 2, vector<int>(cols + 2, 0));
        //left[i][j]表示在grid[i-1][j-1]放置炸弹,向左可以杀死的最大敌人数
        //假设E也可以放置炸弹,当前元素为E,可以杀死的敌人数加一
        //当前元素为W,不能放置炸弹,可以杀死的人数为0
        //当前元素为0,可以杀死的人数不变
        for (int i = 1; i <= rows; ++i)
        {
            for (int j = 1; j <= cols; ++j)
            {
                if (grid[i - 1][j - 1] == 'E')
                    left[i][j] = left[i][j - 1] + 1;
                else if (grid[i - 1][j - 1] == 'W')
                    left[i][j] = 0;
                else
                    left[i][j] = left[i][j - 1];
            }
        }
        //right[i][j]表示在grid[i - 1][j - 1]放置炸弹, 向右可以杀死的最大敌人数
        for (int i = 1; i <= rows; ++i)
        {
            for (int j = cols; j >= 1; --j)
            {
                if (grid[i - 1][j - 1] == 'E')
                    right[i][j] = right[i][j + 1] + 1;
                else if (grid[i - 1][j - 1] == 'W')
                    right[i][j] = 0;
                else
                    right[i][j] = right[i][j + 1];
            }
        }
        //up[i][j]表示在grid[i-1][j-1]放置炸弹,向上可以杀死的最大敌人数
        for (int j = 1; j <= cols; ++j)
        {
            for (int i = 1; i <= rows; ++i)
            {
                if (grid[i - 1][j - 1] == 'E')
                    up[i][j] = up[i-1][j] + 1;
                else if (grid[i - 1][j - 1] == 'W')
                    up[i][j] = 0;
                else
                    up[i][j] = up[i - 1][j];
            }
        }
        //down[i][j]表示在grid[i-1][j-1]放置炸弹,向下可以杀死的最大敌人数
        for (int j = 1; j <= cols; ++j)
        {
            for (int i = rows; i >= 1; --i)
            {
                if (grid[i - 1][j - 1] == 'E')
                    down[i][j] = down[i + 1][j] + 1;
                else if (grid[i - 1][j - 1] == 'W')
                    down[i][j] = 0;
                else
                    down[i][j] = down[i + 1][j];
            }
        }
        int res = 0;
        //仅在grid[i-1][j-1]为0时计算其上下左右可以杀死敌人的总数
        for (int i = 1; i <= rows; ++i)
        {
            for (int j = 1; j <= cols; ++j)
            {
                if (grid[i - 1][j - 1] == '0')
                {
                    res = max(res, left[i][j] + right[i][j] + up[i][j] + down[i][j]);
                }
            }
        }
        return res;
    }
};
#endif
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值