给出
n
≤
30
,
m
≤
30
n\leq30,m\leq30
n≤30,m≤30的网格图,然后一些格子为
1
1
1表示有障碍物,一些格子为
0
0
0则没有,没有障碍物的格子是可达的。然后对于两个可达的格子的距离是它们的欧几里得距离,你有
T
T
T次机会可以消除一个障碍,现在请你求出最大的距离。
n
n
n的规模很小,直接枚举每个点作为起点,然后求到所有点最短路,这里最短路指的是
1
1
1的数量。然后与
T
T
T比较,小于
T
T
T可以用当前距离更新答案。
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int inf=0x3f3f3f3f;
const ll INF=LONG_LONG_MAX;
const int N=31;
int n,m,t;
int mp[N][N];
char s[N];
bool inq[N][N];
int dis[N][N];
int dx[]={1,-1,0,0};
int dy[]={0,0,-1,1};
struct node{ int x,y; };
double sq(double x) {
return x*x;
}
double spfa(int x,int y) {
queue<node> q;
for(int i=1;i<=n;i++) {
for(int j=1;j<=m;j++) {
dis[i][j]=1e9;
}
}
dis[x][y]=0;
inq[x][y]=1;
q.push({x,y});
while(!q.empty()) {
node cur=q.front();
q.pop();
int x=cur.x;
int y=cur.y;
inq[x][y]=0;
for(int i=0;i<4;i++) {
int nx=x+dx[i];
int ny=y+dy[i];
if(nx<1||nx>n||ny<1||ny>m) continue;
if(mp[nx][ny]==0) {
if(dis[nx][ny]>dis[x][y]) {
dis[nx][ny]=dis[x][y];
if(!inq[nx][ny]) {
inq[nx][ny]=1;
q.push({nx,ny});
}
}
}
else if(mp[nx][ny]==1) {
if(dis[nx][ny]>dis[x][y]+1) {
dis[nx][ny]=dis[x][y]+1;
if(!inq[nx][ny]) {
inq[nx][ny]=1;
q.push({nx,ny});
}
}
}
}
}
double ans=0.0;
for(int i=1;i<=n;i++) {
for(int j=1;j<=m;j++) {
if(dis[i][j]<=t) {
ans=max(ans,sqrt(sq(x-i)+sq(y-j)));
}
}
}
return ans;
}
int main() {
scanf("%d%d%d",&n,&m,&t);
for(int i=1;i<=n;i++) {
scanf("%s",s+1);
for(int j=1;j<=m;j++)
mp[i][j]=s[j]-'0';
}
double ans=0.0;
for(int i=1;i<=n;i++) {
for(int j=1;j<=m;j++) {
if(mp[i][j]==0) {
ans=max(ans,spfa(i,j));
}
}
}
printf("%.6lf\n",ans);
return 0;
}