[SCOI2009]最长距离

Description
windy有一块矩形土地,被分为 NM 块 11 的小格子。 有的格子含有障碍物。 如果从格子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 1
3 3 0
001
001
110

Sample Output 1
1.414214

Sample Output 2
3.605551

Sample Input 2
4 3 0
001
001
011
000

Sample Output 3
2.828427

Sample Input 3
3 3 1
001
001
001

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 。


N,M很小,我们可以直接跑N×M次SPFA,求出任意两点之间经过最少障碍数,然后\(N^2\)枚举,判断障碍数,直接统计答案

/*program from Wolfycz*/
#include<cmath>
#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
#define inf 0x7f7f7f7f
#define sqr(x) ((x)*(x))
using namespace std;
typedef long long ll;
typedef unsigned int ui;
typedef unsigned long long ull;
inline char gc(){
	static char buf[1000000],*p1=buf,*p2=buf;
	return p1==p2&&(p2=(p1=buf)+fread(buf,1,1000000,stdin),p1==p2)?EOF:*p1++;
}
inline int frd(){
	int x=0,f=1;char ch=gc();
	for (;ch<'0'||ch>'9';ch=gc())	if (ch=='-')    f=-1;
	for (;ch>='0'&&ch<='9';ch=gc())	x=(x<<1)+(x<<3)+ch-'0';
	return x*f;
}
inline int read(){
	int x=0,f=1;char ch=getchar();
	for (;ch<'0'||ch>'9';ch=getchar())	if (ch=='-')	f=-1;
	for (;ch>='0'&&ch<='9';ch=getchar())	x=(x<<1)+(x<<3)+ch-'0';
	return x*f;
}
inline void print(int x){
	if (x<0)    putchar('-'),x=-x;
	if (x>9)	print(x/10);
	putchar(x%10+'0');
}
const int N=30;
const int dx[4]={-1,1,0,0};
const int dy[4]={0,0,-1,1};
int dist[N+10][N+10][N+10][N+10];
int n,m,T;
struct S1{
	int x,y;
	void insert(int _x,int _y){x=_x,y=_y;}
}h[N*N+10];
char map[N+10][N+10];
bool vis[N+10][N+10];
bool in_map(int x,int y){return x>0&&x<=n&&y>0&&y<=m;}
void SPFA(int x,int y,int dis[N+10][N+10]){
	memset(vis,0,sizeof(vis));
	h[1].insert(x,y),dis[x][y]=(map[x][y]=='1'),vis[x][y]=1;
	int head=0,tail=1;
	while (head!=tail){
		if (++head>N*N)	head=1;
		int Nx=h[head].x,Ny=h[head].y;
		for (int k=0;k<4;k++){
			int tx=Nx+dx[k],ty=Ny+dy[k];
			if (in_map(tx,ty)&&dis[tx][ty]>dis[Nx][Ny]+(map[tx][ty]=='1')){
				dis[tx][ty]=dis[Nx][Ny]+(map[tx][ty]=='1');
				if (!vis[tx][ty]){
					if (++tail>N*N)	tail=1;
					h[tail].insert(tx,ty);
					vis[tx][ty]=1;
				}
			}
		}
		vis[Nx][Ny]=0;
	}
}
int main(){
	n=read(),m=read(),T=read();
	memset(dist,63,sizeof(dist));
	for (int i=1;i<=n;i++)	scanf("%s",map[i]+1);
	for (int i=1;i<=n;i++)
		for (int j=1;j<=n;j++)
			SPFA(i,j,dist[i][j]);
	double Ans=0;
	for (int ox=1;ox<=n;ox++)
		for (int oy=1;oy<=m;oy++)
			for (int ex=1;ex<=n;ex++)
				for (int ey=1;ey<=m;ey++)
					if (dist[ox][oy][ex][ey]<=T)
						Ans=max(Ans,sqrt(sqr(ex-ox)+sqr(ey-oy)));
	printf("%.6lf\n",Ans);
	return 0;
}
posted @ 2018-11-21 10:49  Wolfycz  阅读(167)  评论(0编辑  收藏  举报