【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
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
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 }