AmazingCounters.com

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 。

 

思路:很自然的会想到枚举开始结束两个格子,然后如果那么俩之间可以删掉T个格子就可以计算了,至于如何计算可以上下左右建边,跑最短路,想到这个思路的时候我一直觉得会TLE,结果CP去敲了,AC!!!!果然大胆暴力出奇迹

 

 1 #include<iostream>
 2 #include<cstdio>
 3 #include<queue>
 4 #include<cmath>
 5 #include<cstring>
 6 #define maxn 1000
 7 #define abs(x) (((x)>0)?(x):(-(x)))
 8 using namespace std;
 9 const int dx[10]={0,0,0,1,-1};
10 const int dy[10]={0,1,-1,0,0};
11 char ch[31][31];
12 int head[maxn],next[maxn],point[maxn],value[maxn];
13 int dist[maxn],now;
14 void add(int x,int y,int v)
15 {
16     next[++now] = head[x];
17     head[x] = now;
18     point[now] = y;
19     value[now] = v;
20 }
21 int dis(int x,int y,int xx,int yy)
22 {
23     int u = abs(x-xx),v = abs(y-yy);
24     return u*u+v*v;
25 }
26 void spfa(int s)
27 {
28     memset(dist,-1,sizeof(dist));
29     queue<int>q;
30     q.push(s);
31     dist[s]=0;
32     int visit[maxn];
33     visit[s]=1;
34     while(!q.empty())
35     {
36         int k = q.front();
37         q.pop();
38         visit[k]=0;
39         for(int i=head[k];i;i=next[i])
40         {
41             int u = point[i];
42             if(dist[u]==-1 || dist[u]>dist[k]+value[i])
43             {
44                 dist[u]=dist[k]+value[i];
45                 if(!visit[u])
46                 {
47                     q.push(u);
48                     visit[u] = 1;
49                 }
50             }
51         }
52     }
53 }
54 int main()
55 {
56     int n , m , t;
57     scanf("%d%d%d",&n,&m,&t);
58     for(int i=1;i<=n;i++)scanf("%s",ch[i]+1);
59     for(int i=1;i<=n;i++)
60     {
61         for(int j=1;j<=m;j++)
62         {
63             for(int k=1;k<=4;k++)
64             {
65                 int xx = i+dx[k],yy = j + dy[k];
66                 if(xx<1 || yy<1 || xx >n || yy>m)continue;
67                 add((i-1)*m+j,(xx-1)*m+yy,ch[xx][yy]=='0'?0:1);
68             }
69         }
70     }
71     int ans = 0;
72     for(int i=1;i<=n;i++)
73     {
74         for(int j=1;j<=m;j++)
75         {
76             int u = (i-1)*m+j;
77             spfa(u);
78             for(int x=1;x<=n;x++)
79             {
80                 for(int y = 1;y<=m;y++)
81                 {
82                     int v = (x-1)*m+y;
83                     int uu = dis(i,j,x,y);
84                     if(dist[(x-1)*m+y]+ch[i][j]-'0'<=t && ans < uu)
85                     {
86                         ans = uu;
87                     }
88                 }
89             }
90         }
91     }
92     printf("%.6f\n",sqrt(ans));
93     return 0;
94 }

 

posted @ 2015-08-05 18:00  philippica  阅读(277)  评论(0编辑  收藏  举报