[bzoj2709][二分]迷宫花园

20 篇文章 0 订阅
17 篇文章 0 订阅

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;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值