zoukankan      html  css  js  c++  java
  • cf413E Maze 2D

    E. Maze 2D
    time limit per test 2 seconds
    memory limit per test 256 megabytes
    input standard input
    output standard output

    The last product of the R2 company in the 2D games' field is a new revolutionary algorithm of searching for the shortest path in a 2 × nmaze.

    Imagine a maze that looks like a 2 × n rectangle, divided into unit squares. Each unit square is either an empty cell or an obstacle. In one unit of time, a person can move from an empty cell of the maze to any side-adjacent empty cell. The shortest path problem is formulated as follows. Given two free maze cells, you need to determine the minimum time required to go from one cell to the other.

    Unfortunately, the developed algorithm works well for only one request for finding the shortest path, in practice such requests occur quite often. You, as the chief R2 programmer, are commissioned to optimize the algorithm to find the shortest path. Write a program that will effectively respond to multiple requests to find the shortest path in a 2 × n maze.

    Input

    The first line contains two integers, n and m (1 ≤ n ≤ 2·105; 1 ≤ m ≤ 2·105) — the width of the maze and the number of queries, correspondingly. Next two lines contain the maze. Each line contains n characters, each character equals either '.' (empty cell), or 'X' (obstacle).

    Each of the next m lines contains two integers vi and ui (1 ≤ vi, ui ≤ 2n) — the description of the i-th request. Numbers viui mean that you need to print the value of the shortest path from the cell of the maze number vi to the cell number ui. We assume that the cells of the first line of the maze are numbered from 1 to n, from left to right, and the cells of the second line are numbered from n + 1 to 2n from left to right. It is guaranteed that both given cells are empty.

    Output

    Print m lines. In the i-th line print the answer to the i-th request — either the size of the shortest path or -1, if we can't reach the second cell from the first one.

    Sample test(s)
    input
    4 7
    .X..
    ...X
    5 1
    1 3
    7 7
    1 4
    6 1
    4 7
    5 7
    output
    1
    4
    0
    5
    2
    2
    2
    input
    10 3
    X...X..X..
    ..X...X..X
    11 7
    7 18
    18 10
    output
    9
    -1
    3

     这……线段树神题啊

    但是这是道馆之战的弱化版……

    道馆之战是树上的情况,这题只是一条链的情况

    用线段树维护每一个1*2的格子从第一格能不能到第一格、从第一格能不能到第二格、从第二格能不能到第一格、从第二格能不能到第二格

    #include<cstdio>
    #include<iostream>
    #define LL long long
    #define inf 0x7ffffff
    #define pa pair<int,int>
    #define pi 3.1415926535897932384626433832795028841971
    using namespace std;
    inline LL read()
    {
        LL x=0,f=1;char ch=getchar();
        while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}
        while(ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getchar();}
        return x*f;
    }
    struct segtree{
    	int l,r;
    	int a_to_a,a_to_b,b_to_a,b_to_b;
    }tree[1000010];
    segtree query;
    bool mrk[2][200010];
    int n,m,x0,y0,x1,y1;
    segtree merge(segtree a,segtree b)
    {
    	segtree k;
    	k.a_to_a=k.a_to_b=k.b_to_a=k.b_to_b=-1;
    	k.l=min(a.l,b.l); k.r=max(a.r,b.r);
    	
    	if (a.a_to_a!=-1&&b.a_to_a!=-1)k.a_to_a=a.a_to_a+b.a_to_a+1;
    	if (a.a_to_b!=-1&&b.b_to_a!=-1)
    	{
    		if (k.a_to_a==-1)k.a_to_a=a.a_to_b+b.b_to_a+1;
    		else k.a_to_a=min(k.a_to_a,a.a_to_b+b.b_to_a+1);
    	}
    	
    	if (a.a_to_a!=-1&&b.a_to_b!=-1)k.a_to_b=a.a_to_a+b.a_to_b+1;
    	if (a.a_to_b!=-1&&b.b_to_b!=-1)
    	{
    		if (k.a_to_b==-1)k.a_to_b=a.a_to_b+b.b_to_b+1;
    		else k.a_to_b=min(k.a_to_b,a.a_to_b+b.b_to_b+1);
    	}
    	
    	if (a.b_to_a!=-1&&b.a_to_a!=-1)k.b_to_a=a.b_to_a+b.a_to_a+1;
    	if (a.b_to_b!=-1&&b.b_to_a!=-1)
    	{
    		if (k.b_to_a==-1)k.b_to_a=a.b_to_b+b.b_to_a+1;
    		else k.b_to_a=min(k.b_to_a,a.b_to_b+b.b_to_a+1);
    	}
    	
    	if (a.b_to_a!=-1&&b.a_to_b!=-1)k.b_to_b=a.b_to_a+b.a_to_b+1;
    	if (a.b_to_b!=-1&&b.b_to_b!=-1)
    	{
    		if (k.b_to_b==-1)k.b_to_b=a.b_to_b+b.b_to_b+1;
    		else k.b_to_b=min(k.b_to_b,a.b_to_b+b.b_to_b+1);
    	}
    	return k;
    }
    inline void buildtree(int now,int l,int r)
    {
    	tree[now].l=l;tree[now].r=r;
    	if (l==r)
    	{
    		tree[now].a_to_a=tree[now].a_to_b=tree[now].b_to_a=tree[now].b_to_b=-1;
    		if (mrk[0][l])tree[now].a_to_a=0;
    		if (mrk[1][l])tree[now].b_to_b=0;
    		if (mrk[0][l]&&mrk[1][l])
    		{
    			tree[now].a_to_b=1;
    			tree[now].b_to_a=1;
    		}
    		return;
    	}
    	int mid=(l+r)>>1;
    	buildtree(now<<1,l,mid);
    	buildtree(now<<1|1,mid+1,r);
    	tree[now]=merge(tree[now<<1],tree[now<<1|1]);
    }
    inline void work(int now,int x,int y)
    {
    	int l=tree[now].l,r=tree[now].r;
    	if (l==x&&r==y)
    	{
    		if (!query.l)query=tree[now];
    		else query=merge(query,tree[now]);
    		return;
    	}
    	int mid=(l+r)>>1;
    	if (y<=mid)work(now<<1,x,y);
    	else if (x>mid)work(now<<1|1,x,y);
    	else 
    	{
    		work(now<<1,x,mid);
    		work(now<<1|1,mid+1,y);
    	}
    }
    inline int ask(int x0,int y0,int x1,int y1)
    {
    	query.l=query.r=0;
    	work(1,y0,y1);
    	if (!x0&&!x1)return query.a_to_a;
    	if (!x0&&x1)return query.a_to_b;
    	if (x0&&!x1)return query.b_to_a;
    	if (x0&&x1)return query.b_to_b;
    }
    int main()
    {
    	n=read();m=read();
    	for(int i=0;i<=1;i++)
    	for(int j=1;j<=n;j++)
    	{
    		char ch=getchar();while (ch!='X'&&ch!='.')ch=getchar();
    		if (ch=='.')mrk[i][j]=1;
    	}
    	buildtree(1,1,n);
    	for(int i=1;i<=m;i++)
    	{
    		y0=read();y1=read();x0=x1=0;
    		if ((y0-1)%n+1>(y1-1)%n+1)swap(y0,y1);
    		if (y0>n){x0=1;y0-=n;}
    		if (y1>n){x1=1;y1-=n;}
    		printf("%d
    ",ask(x0,y0,x1,y1));
    	}
    }
    

      

    ——by zhber,转载请注明来源
  • 相关阅读:
    app爬虫(python)开发——通过docker部署多任务端app应用数据抓取系统(终结篇)
    app爬虫(python)开发——app软件数据抓取进阶之实战笔记
    app爬虫(python)开发——简单app数据抓取入门实战案例笔记
    app爬虫(python)开发——移动端自动化控制工具(appium,inspector等)笔记
    JavaCV FFmpeg采集摄像头YUV数据
    java安全编码指南之:lock和同步的正确使用
    《.net之美》之读书笔记(二) C#中的泛型
    跟我一起学.NetCore之WebApi接口裸奔有风险(Jwt)
    一个爬虫的故事:这是人干的事儿?
    从零开始针对 .NET 应用的 DevOps 运营实践
  • 原文地址:https://www.cnblogs.com/zhber/p/4151257.html
Copyright © 2011-2022 走看看