3785. 战舰
#include <bits/stdc++.h>
using namespace std;
int main() {
int n, k;
cin >> n >> k;
vector<vector<int>> a(n + 1, vector<int>(n + 1));
for(int i = 1; i <= n; i++) {
for(int j = 1; j <= n; j++) {
char c;
cin >> c;
if(c == '.') {
a[i][j] = 1;
}
}
}
vector<vector<int>> left(n + 2, vector<int>(n + 2));
vector<vector<int>> right(n + 2, vector<int>(n + 2));
vector<vector<int>> up(n + 2, vector<int>(n + 2));
vector<vector<int>> down(n + 2, vector<int>(n + 2));
for(int i = 1; i <= n; i++) {
for(int j = 1; j <= n; j++) {
if(a[i][j]) {
left[i][j] = left[i][j - 1] + 1;
up[i][j] = up[i - 1][j] + 1;
}
left[i][j] = min(left[i][j], k);
up[i][j] = min(up[i][j], k);
}
}
for(int i = n; i >= 1; i--) {
for(int j = n; j >= 1; j--) {
if(a[i][j]) {
right[i][j] = right[i][j + 1] + 1;
down[i][j] = down[i + 1][j] + 1;
}
right[i][j] = min(right[i][j], k);
down[i][j] = min(down[i][j], k);
}
}
int ret = 0, x = 1, y = 1;
for(int i = 1; i <= n; i++) {
for(int j = 1; j <= n; j++) {
if(a[i][j]) {
int cnt = max(left[i][j] + right[i][j] - k, 0) + max(up[i][j] + down[i][j] - k, 0);
if(ret < cnt) {
ret = cnt;
x = i;
y = j;
}
}
}
}
cout << x << " " << y << endl;
return 0;
}
题解:用了类似前缀和的方法去记录left,right,up,down四个数组,分别表示点(i,j)往左,右,上,下分别可以有多少种变换,变换的最大长度不超过船长,也就是k,最后再把相同的变化去掉,再做比较就可得出最终答案。