您的位置:首页 > 其它

[bzoj2709][二分]迷宫花园

2018-02-01 11:00 253 查看
Description

普通得甚至有些二逼的矮穷挫少年——Dios,不可避免地遇到了他生命中的劫数,白富

美少女 Nyution。但是按照正常的校园故事的发展,Nyution 是无论如何不会喜欢上各方面

条件都差到不行的 Dios 的。不过,Dios 还是面对 Nyution 颤抖着说出了那三个字。Nyution

既不想过分地让 Dios 伤心,又不想接受她根本看不上的 Dios,于是决定让 Dios 走一个建在

她家后院里的迷宫花园——如果 Dios 能很快地从起点走到终点,证明他的聪明才智,Nyution

就答应他的表白。

当然 Nyution 敢这么说肯定是有准备的。Nyution 的花园可以看做一个迷宫,在迷宫内

部有起点和终点。Dios 要从起点走到终点,并且他只能选择前后左右四个方向行走,而且

显然不能走到篱笆上,也不能走出迷宫的边界。Nyution 经过仔细的调查发现,Dios 移动到

相邻格子的耗时肯定是 1。同时,Nyution 将在 Dios 的挑战开始前,通过进行适当的路面调

整,使 Dios 在南北方向(数据中的上下方向)的移动时间由 1 变成实数v 。首先,Nyution

不能让 Dios 过快地到达终点,这样她就得接受表白;其次,Nyution 也不想让 Dios 开了小

宇宙之后还是过慢地到达终点,这样显得她在刁难 Dios。最后她确定了一个实数 L ——就

是最坏情况(也就是 Dios 最神勇威武耗时最短的情况)下,Dios 将花费 L 的时间由起点到

达终点。但是 Nyution 显然不会求此时的v 值,于是她找到了一向以算法达人著称的你。你

当然不会拒绝白富美 Nyution 的请求,决定帮她算出此时的v 。

由于 Nyution 不仅是白富美同时也是三好学生,所以她肯定不会给你一个无解的任务。

并且,Nyution 的迷宫中一定没有水平的从起点到终点的通路。

Input

测试文件中包含若干个测试点。

每个测试点包含两行。第一行包含一个整数 N ,表示有 N 个木偶。

接下来一行 N 个整数,第i 个整数 pi ,表示第i 个木偶及其原装提线的特征值。

Output

一行一个整数,表示最多可能扔掉多少个木偶。

Sample Input

5

10.28 9 9

#

#

# # #

S#

#

#

###

E

#

4.67 9 9

#

##

#S#

# E

#

##

#####

#

#

39.06 9 9

#

#

# # #

E# #

# # #

###

# #S#

#

#

24.00 9 9

#

#

# ##

#

S## E

#

# #

#

#

25.28 9 9

#

S##E#

### #

##

##

#

# #

#

#

Sample Output

0.41000

4.67000

3.34000

5.00000

1.69000

HINT

对于 10% 的数据,满足1 <= N <= 10。

对于 20% 的数据,满足1<= N <= 20。

对于 100% 的数据,满足1<= N <= 50 ,1 <= pi <= 100。

题解

二分答案之后spfa check一下就可以了。。

有点卡精度

#include<cstdio>
#include<cstring>
#include<cstdlib>
#include<algorithm>
#include<cmath>
#include<queue>
using namespace std;
const int dx[4]={0,-1,0,1};
const int dy[4]={-1,0,1,0};
const double eps=1e-7;
double L;
int n,m,stx,sty,edx,edy;
int mp[110][110];
bool v[110][110];
char st[110][110];
struct node
{
int x,y;
};
int head,tail;
double d[110][110];
queue<node> list;
double chk(double p)
{
for(int i=1;i<=n;i++)for(int j=1;j<=m;j++)d[i][j]=123456.0;
d[stx][sty]=0.0;
head=1;tail=2;
memset(v,false,sizeof(v));
v[stx][sty]=true;
node n1;n1.x=stx;n1.y=sty;
list.push(n1);
while(!list.empty())
{
node tmp=list.front();
for(int i=0;i<=3;i++)
{
int x=tmp.x+dx[i],y=tmp.y+dy[i];
double dis;
if(y==tmp.y)dis=p;
else dis=1.0;
if(mp[x][y]!=-1)
{
if(d[x][y]>d[tmp.x][tmp.y]+dis)
{
d[x][y]=d[tmp.x][tmp.y]+dis;
if(v[x][y]==false)
{
v[x][y]=true;
node cnt;
cnt.x=x;cnt.y=y;
list.push(cnt);
}
}
}
}
v[tmp.x][tmp.y]=false;
list.pop();
}
return d[edx][edy];
}
int main()
{
//freopen("maze.in","r",stdin);
//freopen("maze.out","w",stdout);
int T;
scanf("%d\n",&T);
for(int tt=1;tt<=T;tt++)
{
memset(mp,-1,sizeof(mp));
scanf("%lf %d %d\n",&L,&n,&m);
for(int i=1;i<=n;i++)
{
gets(st[i]+1);
//  if(tt!=T || tt==T && i!=n)getchar();
for(int j=1;j<=m;j++)
{
if(st[i][j]=='S')stx=i,sty=j;
if(st[i][j]=='E')edx=i,edy=j;
if(st[i][j]!='#')mp[i][j]=0;
}
}
double l=0.0,r=10.0;
while(r-l>eps)
{
double mid=(l+r)/2.0;
if(chk(mid)>L)r=mid;
else l=mid;
}
printf("%.5lf\n",l);
}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: