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