大体就是给一个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 ",ans); }