20241114 AC 避难 薯片
避难:
题意大概是让你找一块陆地,这块陆地的值为上下左右离海最近的位置。
最后让你求这些陆地中,哪一个的值最大,并且输出。
思路:
直接递推
设d[x][y]表示(x,y)格子的答案,同时对大海的格子(x,y)令d[x][y]=0。
可以从四个方向(左上、右下、左下、右上)递推更新,四个方向递推完成后的d就是答案。
以左上方为例,d[x][y]=min(d[x][y-1],d[x-1][y-1],d[x-1][y])+1,递推方向为从上到下、从左到右。其他几个方向类似。时间复杂度O(HW)。
#include<bits/stdc++.h>
using namespace std;
int h,w,d[3010][3010],maxn;
char c[3010][3010];
int main(){
freopen("refuge.in","r",stdin);
freopen("refuge.out","w",stdout);
cin>>h>>w;
for(int i=1;i<=h;i++){
for(int j=1;j<=w;j++){
cin>>c[i][j];
}
}
for(int i=1;i<=h;i++){
for(int j=1;j<=w;j++){
if(c[i][j]=='#')d[i][j]=min(min(d[i][j-1],d[i-1][j-1]),d[i-1][j])+1;
}
}
for(int i=1;i<=h;i++){
for(int j=w;j>=1;j--){
if(c[i][j]=='#')d[i][j]=min(min(min(d[i][j+1],d[i-1][j+1]),d[i-1][j])+1,d[i][j]);
}
}
for(int i=h;i>=1;i--){
for(int j=w;j>=1;j--){
if(c[i][j]=='#')d[i][j]=min(min(min(d[i][j+1],d[i+1][j+1]),d[i+1][j])+1,d[i][j]);
}
}
for(int i=h;i>=1;i--){
for(int j=1;j<=w;j++){
if(c[i][j]=='#')d[i][j]=min(min(min(d[i][j-1],d[i+1][j-1]),d[i+1][j])+1,d[i][j]);
}
}
for(int i=1;i<=h;i++){
for(int j=1;j<=w;j++){
maxn=max(d[i][j],maxn);
}
}
cout<<maxn;
return 0;
}

1395

被折叠的 条评论
为什么被折叠?



