大体就是给一个01矩阵,1不可通行,可以破坏k[0,30]个1方格,问最长欧式距离
脑洞1小时没啥想法。。给正解跪。。居然是跑破坏方块的最短路,然后枚举点对更新答案,只要点对的最短路距离<=k就合法
naive!
#include<iostream>
#include<stdio.h>
#include<algorithm>
#include<queue>
#include<string.h>
#include<math.h>
#include<set>
#include<map>
#include<vector>
#include<iomanip>
#include<stack>
using namespace std;
#define ll long long
#define ull unsigned long long
#define pb push_back
#define mem(a) memset(a,0,sizeof a)
#define FOR(a) for(int i=1;i<=a;i++)
#define sqr(a) (a)*(a)
const int maxn=35*35;
const ll mod=1e9+7;
int n,m,t;
char buf[maxn];
int mp[maxn][maxn];
struct EDGE{int v,w;};
vector<EDGE>G[maxn];
void addedge(int u,int v,int w){
G[u].pb((EDGE){v,w});
}
struct NODE{
int v,d;
friend bool operator<(NODE a,NODE b){return a.d>b.d;}
};
int d[maxn][maxn],vis[maxn];
void dij(int from){
memset(vis,0,sizeof vis);
for(int i=0;i<maxn;i++)d[from][i]=mod;
if(!mp[(from+m-1)/m][from%m!=0?from%m:m])d[from][from]=0;
else d[from][from]=1;
priority_queue<NODE>Q;
NODE now=(NODE){from,0};
Q.push(now);
while(!Q.empty()){
NODE now=Q.top();Q.pop();
int u=now.v;
if(vis[u])continue;
vis[u]=1;
for(int i=0;i<G[u].size();i++){
if(d[from][G[u][i].v]>d[from][u]+G[u][i].w){
d[from][G[u][i].v]=d[from][u]+G[u][i].w;
NODE nxt=(NODE){G[u][i].v,d[from][G[u][i].v]};
Q.push(nxt);
}
}
}
}
int main(){
scanf("%d%d%d",&n,&m,&t);
for(int i=1;i<=n;i++){
scanf("%s",buf+1);
for(int j=1;j<=m;j++)mp[i][j]=buf[j]=='1'?1:0;
}
for(int i=1;i<=n;i++){
for(int j=1;j<=m;j++){
int x=i,y=j;
for(int dx=-1;dx<=1;dx++){
for(int dy=-1;dy<=1;dy++){
if(dx==dy || dx+dy==0)continue;
if(x+dx>n||x+dx<1||y+dy>m||y+dy<1)continue;
if(mp[x+dx][y+dy]){
addedge((x-1)*m+y,(x+dx-1)*m+y+dy,1);
}else{
addedge((x-1)*m+y,(x+dx-1)*m+y+dy,0);
}
}
}
}
}
for(int i=1;i<=n*m;i++){
dij(i);
}
double ans=0;
for(int i=1;i<=n*m;i++){
for(int j=1+i;j<=n*m;j++){
if(d[i][j]<=t){
int yy1=i%m==0?m:i%m;
int yy2=j%m==0?m:j%m;
//if(mp[(i+m-1)/m][yy1])if(d[i][j]==t-1)continue;
ans=max(ans,sqrt(sqr((i+m-1)/m-(j+m-1)/m) + sqr(yy1-yy2)));
}
}
}
printf("%.6lf\n",ans);
}