• [CSP-S模拟测试]:引子(大模拟)


    题目描述

    网上冲浪时,$Slavko$被冲到了水箱里,水箱由上而下竖直平面。示意图如下:


    数字$i$所在的矩形代表一个编号为$i$的水箱。
    1号水箱为水箱中枢,有水管连出。除了$1$号水箱外,其他水箱上方会接进来恰好一条水管,也可能有水管连出。
    连出的水管会从水箱侧面连出去,同一个水箱连出去的水管会在不同的行与侧面连接。每一条水管直接连接两个水箱,这意味着不会把水管分叉也不会出现水管交叉的情况。这样,从一个水箱流入另外一个水箱时,水管的走向始终保持行号增加或保持不变。
    水会源源不断地涌进$1$号水箱直到各个水箱水满为止。帮助$Slavko$计算出各个水箱装满的次序。


    输入格式

    输入会给你一个$n*m$的点阵,点阵字符的全集为${+,|,-,.}$
    水箱:形状是矩形,四角有$+$符号,左右为$|$,上下为$-$,里面包含一个数字代表水箱的编号,如上图。
    管道:一条管道恰好连接两个不同的水箱,$|$表示管道竖直摆放,$-$表示管道水平摆放,其中竖直的管道之间会连接起来,水平的管道会连接起来,$+$连接竖直和水平的管道($+$的上下恰好其中一个为$.$一个为$|$,$+$的左右恰好其中一个为$.$一个为$-$)。
    其余位置用. 来填充。
    输入的第$1$行为两个正整数$n$,$m$。
    接下来$n$行描述点阵的信息,每行有$m$个字符。


    输出格式

    输出水箱被浸满的顺序,每行一个序号。


    样例

    样例输入1:

    12 13
    ..+--+.......
    +-|..|.......
    |.|.1|--+....
    |.+--+..|....
    |......+----+
    +---+..|..2.|
    ....|..+----+
    .+--+........
    .|...........
    +---+........
    |.3.|........
    +---+........

    样例输出1:

    2
    3
    1

    样例输入2:

    8 10
    ..........
    .......+-+
    ...+---|1|
    ...|...+-+
    ...|......
    ..+-+.....
    ..|2|.....
    ..+-+.....

    样例输出2:

    2
    1


    数据范围与提示

    样例解释:

    把输入粘贴到记事本上就一目了然了。

    大概是这样:

    样例1:     

    样例2:

    数据范围:

    $70%$的数据:$1leqslant n,mleqslant 100$。
    $100%$的数据满足:$1leqslant n,mleqslant 1,000$。


    题解

    就是个大模拟,但是细节颇多,注意以下几点:

     $alpha.$可能会出现这种情况:

      

      但是不会出现这种情况:

      

     $eta.$一个水箱可能有多个儿子,但是不会有两个儿子等高。

     $gamma.$注意边界问题。

    时间复杂度:$Theta(hsw)$。

    期望得分:$100$分。

    实际得分:我也不知道……


    代码时刻

    #include<bits/stdc++.h>
    using namespace std;
    struct rec{int x,y,lx,ly,rx,ry,s,s1,lr[100],c[100],son[100];}e[50000];
    int n,m;
    int Map[5000][5000];
    char ch[5000];
    int ex,ey,cnt;
    int ans[100000];
    int que[100000];
    void getson(int x,int y,int id,int d,bool son)
    {
    	if(Map[x][y]==2&&d==2)
    	{
    		for(int i=1;i<=cnt;i++)
    			if(e[i].lx==x&&e[i].ly<y&&e[i].ry>y)
    			{
    				e[id].son[++e[id].s1]=i;
    				break;
    			}
    		return;
    	}
    	if(Map[x][y]==1)
    	{
    		if(Map[x+1][y]==3)getson(x+1,y,id,2,son);
    		if(Map[x][y-1]==2&&d!=1)getson(x,y-1,id,0,son);
    		if(Map[x][y+1]==2&&d!=0)getson(x,y+1,id,1,son);
    	}
    	else if(d==2)getson(x+1,y,id,2,son);
    	else if(d==0)getson(x,y-1,id,d,son);
    	else if(d==1)getson(x,y+1,id,d,son);
    }
    void dfs(int x)
    {
    	if(!e[x].s){ans[++ans[0]]=x;return;}
    	if(e[x].s)
    		for(int i=1;i<=e[x].s;i++)
    			dfs(e[x].son[i]);
    	ans[++ans[0]]=x;
    }
    int main()
    {
    	scanf("%d%d",&n,&m);
    	for(int i=1;i<=n;i++)
    	{
    		scanf("%s",ch+1);
    		for(int j=1;j<=m;j++)
    		{
    			switch(ch[j])
    			{
    				case '+':Map[i][j]=1;break;
    				case '-':Map[i][j]=2;break;
    				case '|':Map[i][j]=3;break;
    			}
    			int sz=0;
    			while(ch[j]>='0'&&ch[j]<='9')
    			{
    				sz=sz*10+ch[j]-'0';
    				j++;
    			}
    			if(sz)
    			{
    				j--;
    				e[++cnt].x=i;
    				e[cnt].y=j;
    				que[cnt]=sz;
    			}
    			if(sz==1){ex=i,ey=j;}
    		}
    	}
    	int flag;
    	for(int i=1;i<=cnt;i++)
    	{
    		flag=e[i].y;
    		while(flag--)if(Map[e[i].x][flag]==3)break;
    		e[i].ly=flag;
    		flag=e[i].y;
    		while(flag++)if(Map[e[i].x][flag]==3)break;
    		e[i].ry=flag;
    		flag=e[i].x;
    		while(flag--)if(Map[flag][e[i].y]==2)break;
    		e[i].lx=flag;
    		flag=e[i].x;
    		while(flag++)if(Map[flag][e[i].y]==2)break;
    		e[i].rx=flag;
    		flag=e[i].rx;
    		if(e[i].ry>n&&e[i].ly==1)goto nxt;
    		while(flag--)
    		{
    			if(Map[flag][e[i].ly-1]==2||Map[flag][e[i].ly-1]==1){e[i].c[++e[i].s]=flag;e[i].lr[e[i].s]=0;}
    			if(Map[flag][e[i].ry+1]==2||Map[flag][e[i].ry+1]==1){e[i].c[++e[i].s]=flag;e[i].lr[e[i].s]=1;}
    			if(flag<e[i].lx)goto nxt;
    		}
    		nxt:;
    	}
    	for(int i=1;i<=cnt;i++)
    		for(int j=1;j<=e[i].s;j++)
    		{
    			if(e[i].lr[j]==0)getson(e[i].c[j],e[i].ly-1,i,0,0);
    			else getson(e[i].c[j],e[i].ry+1,i,1,1);
    		}
    	dfs(1);
    	for(int i=1;i<=cnt;i++)printf("%d
    ",que[ans[i]]);
    	return 0;
    }
     

    rp++

  • 相关阅读:
    spring与hibernate整合使用properties文件分离数据库连接设置
    Android的Selector使用
    Linux中的软链接、硬链接
    JDK自带线程池解析
    shell的控制流程语句
    [转] 对于javascript的function的总结
    [#转#]经典的帖子:多态分析1
    [转]javascript 中数组使用方法汇总
    struts中设置指令牌
    关于指令牌一个有趣的帖子
  • 原文地址:https://www.cnblogs.com/wzc521/p/11352219.html
Copyright © 2020-2023  润新知