AcWing 3785. 战舰
原题链接
Description
给定一个 \(n×n\) 的字符矩阵,表示一片海域。
矩阵中 # 表示暗礁区域,. 表示安全区域。
现在要将一个 \(1×k\) 的战舰投放到海域中。
投放时,战舰不可接触到暗礁区域。
战舰可以横着投放,也可以竖着投放。
在投放完成后,每个安全区域要么包含战舰的一部分,要么不包含。
对于某个安全区域,如果所有可能的投放方式中,共有 \(m\) 种不同的投放方式,满足该区域包含战舰的一部分,那么就称该区域的投放指数为 \(m\)。
请确定投放指数最大的安全区域的位置坐标。
Input
第一行包含两个整数 \(n\) 和 \(k\)。
接下来 \(n\) 行,每行包含一个长度为 \(n\) 的字符串,表示海域。
Output
输出投放指数最大的安全区域的行、列坐标。
行从上到下,从 1 开始计数,列从左到右,从 1 开始计数。
Solution
需要求每个区域最大的投放指数,对每一个单元进行枚举
例如:
红色指针指向的这个区域,船舰可以这样停靠,直到下图:
所以,可以从红色指向区域向左枚举\(l\),直到船舰不停靠在这个区域。同样的,向右枚举\(r\),直到创建不停靠在这个区域,所以对于行来说,这个区域的停靠指数为\(r - l - k\)。
类似地,对列也这样操作, 相加,得到这个区域的停靠指数
Code
#include
#include
#include
using namespace std;
const int N = 110;
int n, k;
char g[N][N];
int main()
{
scanf("%d%d", &n, &k);
for (int i = 1; i <= n; i ++ ) scanf("%s", g[i] + 1);
int x = 1, y = 1, res = 0;
for (int i = 1; i <= n; i ++ )
for(int j = 1; j <= n; j ++)
{
if(g[i][j] == '#') continue;
int l = j, r = j;
while(l >= 1 && g[i][l] == '.' && j - l + 1 <= k) l --;
while(r <= n && g[i][r] == '.' && r - j + 1 <= k) r ++;
int t = max(0, r - l - k);
l = r = i;
while(l >= 1 && g[l][j] == '.' && i - l + 1 <= k) l --;
while(r <= n && g[r][j] == '.' && r - i + 1 <= k) r ++;
t += max(0, r - l - k);
if(t > res)
{
res = t;
x = i, y = j;
}
}
printf("%d %d\n", x, y);
return 0;
}