zoukankan      html  css  js  c++  java
  • [CSP-S模拟测试]:maze(二分答案+最短路)

    题目传送门(内部题88)


    输入格式

    第一行两个数$n,m$。
    第二行四个数$sx,sy,tx,ty$。分别表示起点所在行数、列数,终点所在行数、列数。
    接下来$n$行,每行$m$个数,描述迷宫。
    最后一行一个正实数$s$。


    输出格式

    输出答案$k$,四舍五入保留$3$位小数。(评测时开启逐行比较模式)


    样例

    样例输入:

    4 4
    1 1 4 4
    0 0 1 1
    1 0 0 0
    0 0 1 0
    0 0 0 0
    5

    样例输出:

    0.667


    数据范围与提示

    对于$30\%$的数据:$n,mleqslant 10$
    对于另$10\%$的数据:保证从起点到终点有且只有一条不重复经过同一个点的路径
    对于$100\%$的数据:$n,mleqslant 100,0<sleqslant 10^5$


    题解

    考虑为什么决策有单调性:

      $alpha.$如题,显然只有一组解,所以决策一定单调。

      $eta.$如果$k>1$,那么随着其不断增大,横向走肯定不断增加,直到极限;反之同理。

    所以考虑二分答案$+$最短路就好了。

    注意题目中说$s$是实数,即有可能是小数。

    时间复杂度:$Theta(nmlog nm imes log s)$。

    期望得分:$100$分。

    实际得分:$100$分。


    代码时刻

    #include<bits/stdc++.h>
    using namespace std;
    const double eps=1e-5;
    struct rec{int nxt,to;bool w;}e[100000];
    int head[10001],cnt;
    int n,m;
    int sx,sy,tx,ty;
    bool Map[102][102];
    int tim[102][102],t;
    double dis[10001];
    bool vis[10001];
    double s;
    priority_queue<pair<double,int>,vector<pair<double,int>>,greater<pair<double,int>>>q;
    void add(int x,int y,bool w)
    {
    	e[++cnt].nxt=head[x];
    	e[cnt].to=y;
    	e[cnt].w=w;
    	head[x]=cnt;
    }
    void Dij(int x,double w)
    {
    	dis[x]=0.0;
    	q.push(make_pair(0.0,x));
    	while(!q.empty())
    	{
    		int flag=q.top().second;q.pop();
    		if(vis[flag])continue;
    		vis[flag]=1;
    		for(int i=head[flag];i;i=e[i].nxt)
    		{
    			double d=(e[i].w)?w:1.0;
    			if(dis[e[i].to]>dis[flag]+d)
    			{
    				dis[e[i].to]=dis[flag]+d;
    				q.push(make_pair(dis[e[i].to],e[i].to));
    			}
    		}
    	}
    }
    bool judge(double mid)
    {
    	for(int i=1;i<=t;i++)
    	{
    		vis[i]=0;
    		dis[i]=1000000000.0;
    	}
    	Dij(tim[sx][sy],mid);
    	if(dis[tim[tx][ty]]<s)return 1;
    	return 0;
    }
    int main()
    {
    	scanf("%d%d%d%d%d%d",&n,&m,&sx,&sy,&tx,&ty);
    	for(int i=1;i<=n;i++)
    		for(int j=1;j<=m;j++)
    		{
    			scanf("%d",&Map[i][j]);
    			tim[i][j]=++t;
    		}
    	for(int i=0;i<=n+1;i++)Map[i][0]=Map[i][m+1]=1;
    	for(int i=0;i<=m+1;i++)Map[0][i]=Map[0][n+1]=1;
    	for(int i=1;i<=n;i++)
    		for(int j=1;j<=m;j++)
    		{
    			if(Map[i][j])continue;
    			if(!Map[i-1][j]){add(tim[i][j],tim[i-1][j],1);add(tim[i-1][j],tim[i][j],1);}
    			if(!Map[i+1][j]){add(tim[i][j],tim[i+1][j],1);add(tim[i+1][j],tim[i][j],1);}
    			if(!Map[i][j-1]){add(tim[i][j],tim[i][j-1],0);add(tim[i][j-1],tim[i][j],0);}
    			if(!Map[i][j+1]){add(tim[i][j],tim[i][j+1],0);add(tim[i][j+1],tim[i][j],0);}
    		}
    	scanf("%lf",&s);
    	double lft=0.0,rht=s;
    	while(rht-lft>eps)
    	{
    		double mid=(lft+rht)/2;
    		if(judge(mid))lft=mid;
    		else rht=mid;
    	}
    	printf("%.3lf",lft);
    	return 0;
    }
    

    rp++

  • 相关阅读:
    FluorineFx ASObject自动转换基础类 AutoParseASObject ,用于Flash AMF协议解析
    小东西WinForm的等待窗口
    被VB6搞死。。。。。。。鸟
    请把这个消息提示框拿掉,谢谢
    MS新版Wallop,
    SQL 2000 异数据库数据同步
    企业管理应用平台预览演示版下载
    Microsoft SQL Server 2008 基本安装说明
    怀旧下给自己留个备份,
    PPPOE数据包转换及SharpPcap应用
  • 原文地址:https://www.cnblogs.com/wzc521/p/11743754.html
Copyright © 2011-2022 走看看