zoukankan      html  css  js  c++  java
  • 题解 CF413E 【Maze 2D】

    竟然没人写题解?我来水一篇~~

    其实感觉应该是提高+/省选-的样子,233。

    其实我没咕值子

    先说说思路:

    1. 维护一个[l,r]区间中四个角相互之间的最短路
    2. 查询时用二分

    思路出来了,算法也就出来了,那就是——线段树!

    此处应有掌声

    首先,我们知道线段树是二分维护区间值的。

    然后,我们也知道线段树是二分查找值。

    最后,我们发现这道题没有修改。

    紧接着,我们开始写代码。

    #include<bits/stdc++.h>
    using namespace std;
    int mmp[3][200001];
    #define INF 500000000
    int n;
    int ans;
    char c[300001];
    struct data{
        int d1,d2,d3,d4;		//四个最短路
    };
    struct tree{
        int l, r;
        data d;
    }t[4*200001];				//线段树标准结构体
    data merge(data a,data b)	//合并最短路
    {
        data s;
        s.d1=min(INF,min(a.d1+b.d1,a.d2+b.d3)+1);
        s.d2=min(INF,min(a.d1+b.d2,a.d2+b.d4)+1);
        s.d3=min(INF,min(a.d3+b.d1,a.d4+b.d3)+1);
        s.d4=min(INF,min(a.d3+b.d2,a.d4+b.d4)+1);
        return s;
    }
    void init(int s,int l,int r)	//标准线段树构建
    {
        t[s].l=l,t[s].r=r;
        if(l==r){
            t[s].d.d1=t[s].d.d2=t[s].d.d3=t[s].d.d4=INF;
            if(mmp[1][l]) t[s].d.d1=0;
            if(mmp[2][l]) t[s].d.d4=0;
            if(mmp[1][l]&&mmp[2][l]) t[s].d.d2=t[s].d.d3=1;
            return ;
        }
        int m=(l+r)/2;
        init(2*s,l,m);
        init(2*s+1,m+1,r);
        t[s].d=merge(t[2*s].d,t[2*s+1].d);
    }
    data q(int s,int x,int y)		//查询时的合并
    {
        int l=t[s].l,r=t[s].r;
        if(x==l&&y==r) return t[s].d;
        int m=(l+r)/2;
        /*下面分类讨论不用讲了吧*/
        if(m>=y) return q(2*s,x,y);             //毒瘤呀,少写return
        else if(m<x) return q(2*s+1,x,y);       //毒瘤呀,少写return
        else
            return merge(q(2*s,x,m),q(2*s+1,m+1,y));
    }
    void ask(int x,int y)			//查询最短路
    {
        int a=(x-1)%n+1,b=(y-1)%n+1;
        if(a>b){
            swap(x,y);
            swap(a,b);
        }
        data s=q(1,a,b);			//找到最短路
        /*根据情况返回四种路径的最短路*/
        if(x<=n&&y<=n) ans=s.d1;
        if(x<=n&&y>n) ans=s.d2;
        if(x>n&&y<=n) ans=s.d3;
        if(x>n&&y>n) ans=s.d4;
    }
    int main()						//请从这里开始阅读,这是一个好习惯
    {
        int m;
        cin>>n>>m;
        int i,j;
        for(i=1;i<=2;i++)			//无脑O(2n)读入
        {
        	scanf("%s",c);
        	for(j=1;j<=n;j++)
        	   if(c[j-1]=='.') mmp[i][j]=1;
        }
        init(1,1,n);
        int x,y;
        for(i=1;i<=m;i++){			//无脑查询
            cin>>x>>y;
            ask(x,y);
            if(ans<INF) cout<<ans<<endl;
            else cout<<"-1
    ";
        }
        return (0-0);				//无脑卖萌QAQ
    }
    

    千万记得所有查询都要return!

    为没有出修改题的出题人喝彩!!!

  • 相关阅读:
    学习了数据库中text类型的查找
    通过 .NET Framework 中的 XPath 和 XSLT API 方便地操作 XML 数据
    Windows服务器下用IIS Rewrite组件为IIS设置伪静态方法
    C# 文件压缩与解压(ZIP格式)
    用SharpZipLib来压缩和解压文件(转载)
    Community Server专题二:体系结构(转载)
    在ASP.NET中如何实现和利用URL重写
    Community Server专题一:概述Community Server(转载)
    C#委托之个人理解
    在ASP.NET中实现Url Rewriting
  • 原文地址:https://www.cnblogs.com/Garbage-Only-one/p/11141878.html
Copyright © 2011-2022 走看看