【BZOJ 1295】 [SCOI2009]最长距离

Description

windy有一块矩形土地,被分为 N*M 块 1*1 的小格子。 有的格子含有障碍物。 如果从格子A可以走到格子B,那么两个格子的距离就为两个格子中心的欧几里德距离。 如果从格子A不可以走到格子B,就没有距离。 如果格子X和格子Y有公共边,并且X和Y均不含有障碍物,就可以从X走到Y。 如果windy可以移走T块障碍物,求所有格子间的最大距离。 保证移走T块障碍物以后,至少有一个格子不含有障碍物。

Input

输入文件maxlength.in第一行包含三个整数,N M T。 接下来有N行,每行一个长度为M的字符串,'0'表示空格子,'1'表示该格子含有障碍物。

Output

输出文件maxlength.out包含一个浮点数,保留6位小数。

Sample Input

【输入样例一】
3 3 0
001
001
110


【输入样例二】
4 3 0
001
001
011
000


【输入样例三】
3 3 1
001
001
001

Sample Output

【输出样例一】
1.414214

【输出样例二】
3.605551

【输出样例三】
2.828427

HINT

 

20%的数据,满足 1 <= N,M <= 30 ; 0 <= T <= 0 。 40%的数据,满足 1 <= N,M <= 30 ; 0 <= T <= 2 。 100%的数据,满足 1 <= N,M <= 30 ; 0 <= T <= 30 。

 
逆向思维
枚举两点,用spfa判断到达最少需要移走多少块。。。就完了
 1 #include<cstdio>
 2 #include<cmath>
 3 #include<cstring>
 4 #include<iostream>
 5 using namespace std;
 6 const int fx[4]={0,0,1,-1},fy[4]={-1,1,0,0};
 7 double ans;
 8 struct qq{int x,y;}q[410000];
 9 int map[50][50],dis[50][50];
10 int n,m,t,cnt;
11 char s[50];
12 bool inq[50][50];
13 int sqr(int x) {return x*x;}
14 double calc(int x1,int y1,int x2,int y2){
15     return sqrt(double(sqr(x1-x2)+sqr(y1-y2)));
16 }
17 void spfa(int xx,int yy){
18     int head,tail;
19     head=tail=0;
20     q[++tail].x=xx,q[tail].y=yy;
21     memset(dis,127,sizeof(dis));
22     memset(inq,0,sizeof(inq));
23     dis[xx][yy]=0;
24     inq[xx][yy]=1;
25     while(head<tail){
26         int x=q[++head].x,y=q[head].y;
27         for(int i=0;i<4;i++){
28             if(x+fx[i]<=0||y+fy[i]<=0||x+fx[i]>n||y+fy[i]>m) continue;
29             if(dis[x+fx[i]][y+fy[i]]>dis[x][y]+map[fx[i]+x][y+fy[i]]){
30                 dis[x+fx[i]][y+fy[i]]=dis[x][y]+map[fx[i]+x][y+fy[i]];
31                 if(!inq[x+fx[i]][y+fy[i]]){
32                     inq[x+fx[i]][y+fy[i]]=1;
33                     q[++tail].x=fx[i]+x,q[tail].y=fy[i]+y;
34                 }
35             }
36         }
37         inq[x][y]=0;
38     }
39 }
40  
41 void ch(int i,int j){
42     for(int ii=1;ii<=n;ii++)
43     for(int jj=1;jj<=m;jj++)
44     if(dis[ii][jj]<=t-map[i][j]) ans=max(ans,calc(ii,jj,i,j));
45 }
46  
47 int main(){
48     scanf("%d%d%d",&n,&m,&t);
49     for(int i=1;i<=n;i++){
50         scanf("%s",s+1);
51         for (int j=1;j<=m;j++) 
52             map[i][j]=s[j]-'0';
53     }
54     for(int i=1;i<=n;i++)
55         for(int j=1;j<=m;j++){
56             spfa(i,j);
57             ch(i,j);
58             }
59     printf("%.6lf",ans);
60 }

 

你可能感兴趣的:(【BZOJ 1295】 [SCOI2009]最长距离)