[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%$的数据:$1\leqslant n,m\leqslant 100$。
$100%$的数据满足:$1\leqslant n,m\leqslant 1,000$。
题解
就是个大模拟,但是细节颇多,注意以下几点:
$\alpha.$可能会出现这种情况:
但是不会出现这种情况:
$\beta.$一个水箱可能有多个儿子,但是不会有两个儿子等高。
$\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\n",que[ans[i]]);
return 0;
}
rp++
[CSP-S模拟测试]:引子(大模拟)的更多相关文章
- [CSP-S模拟测试]:跳房子(模拟)
题目描述 跳房子,是一种世界性的儿童游戏,也是中国民间传统的体育游戏之一.跳房子是在$N$个格子上进行的,$CYJ$对游戏进行了改进,该成了跳棋盘,改进后的游戏是在一个$N$行$M$列的棋盘上进行,并 ...
- [CSP-S模拟测试]:线性代数(模拟)
题目传送门(内部题113) 输入格式 第一行一个正整数$n$. 接下来$n$行,每行$n$个整数,描述$C$矩阵.保证输入的是一个林先森矩阵. 输出格式 若不可能实现,则输出一行$Impossible ...
- [CSP-S模拟测试]:Reverse(模拟+暴力+剪枝)
题目描述 小$G$有一个长度为$n$的$01$串$T$,其中只有$T_S=1$,其余位置都是$0$.现在小$G$可以进行若干次以下操作: $\bullet$选择一个长度为K的连续子串($K$是给定的常 ...
- [CSP-S模拟测试]:reverse(模拟)
题目传送门(内部题56) 输入格式 第一行包含一个整数:$T$,表示数据组数.接下来$T$行,每行包含两个字符串:$a\ b$. 输出格式 对于每组数据,如果存在$c$,输出最长的情况下字典序最大的$ ...
- [考试反思]0719NOIP模拟测试6 + 0722NOIP模拟测试7
连续爆炸,颇为愉快. 第6次:Rank #4 第7次:Rank #9 对于第6次考试,个人比较满意,因为T1只是差了一个卡常. 因为在考试前两天刚讲了矩阵,满脑子都是矩阵,还想到了循环矩阵优化. 整个 ...
- csp-s模拟测试112 & csp-s模拟测试113
考前两天模拟. Day1直接炸飞,T1浪费的时间太长,对拍+调试了一个多小时但复杂度还不能过,最后5分钟想出来了解决方案但是已经打不出来了.T2读入出了事故RE0.T3打了假贪心. Day2心态几乎也 ...
- [CSP-S模拟测试]:集合论(模拟)
题目传送门(内部题73) 输入格式 输入文件$jihe.in$ 第一行一个整数$m$,表示操作的次数. 接下来$m$行,每行描述一个操作. 每行的开始都是一个数字,$1,2,3,4$依次代表$unio ...
- [CSP-S模拟测试]:砖块(模拟)
题目描述 在一个二维网格平面上,一个网格的坐标由其左下角的点的坐标定义$(x,y)$.在一个二维网格平面上,一个网格的坐标由其左下角的个点的坐标定义$(0,0)$的区域中,此时存在高度为$k$的初始砖 ...
- [CSP-S模拟测试]:五子棋(模拟)
题目传送门(内部题122) 输入格式 输入文件第一行为一个正整数$n$,表示双方总共下了多少步棋. 接下来$n$行,输入文件每行两个正整数.第$i$行的两个数$x,y$表示第$i$步的棋子下在了第$x ...
随机推荐
- HAWQ技术总结
HAWQ技术总结: 1. 官网: http://hawq.incubator.apache.org/ 2. 特性 2.1 sql支持完善 ANSI SQL标准,OLAP扩展,标准JDBC/ODBC支持 ...
- Android Framework中Thread类
Thread类是Android为线程操作而做的一个封装.代码在Thread.cpp中,其中还封装了一些与线程同步相关的类. Thread类 Thread类的构造函数中的有一个canCallJava T ...
- PHPstorm Xdebugger最全详细
0 Xdebug调试的原理(选看) 图0-1 单机调试原理示意图 图0-2 多机调试原理示意图 对于PHP开发,初来咋到,开发环境的搭建和理解感觉是最烦人的一件事了.不像JAVA,打开一个Eclips ...
- Java:CAS(乐观锁)
本文讲解CAS机制,主要是因为最近准备面试题,发现这个问题在面试中出现的频率非常的高,因此把自己学习过程中的一些理解记录下来,希望能对大家也有帮助. 什么是悲观锁.乐观锁?在java语言里,总有一些名 ...
- JDK11 | 第五篇 : 启动单个Java源代码文件的程序
文章首发于公众号<程序员果果> 地址 : https://mp.weixin.qq.com/s/h1L4FmzVSix434gVt8Fc7w 一.简介 JEP330-启动单文件代码程序(L ...
- SCUT - 153 - 小马哥和他的山脉 - 线段树
https://scut.online/p/153 其实不需要用线段树,只关心相邻元素的差,像神仙那样用差分就可以O1维护的. 但是我偏要用. 交之前写的那个,注意没有st本身的线段树只有lazy标记 ...
- 问题 M: 最亲密的x个人
问题 M: 最亲密的x个人 时间限制: 1 Sec 内存限制: 128 MB提交: 412 解决: 38[提交] [状态] [命题人:jsu_admin] 题目描述 有一天,地球受到了降维打击,从 ...
- EPROCESS ETHREAD PEB重要成员
-----------------------------------------------------------------------win7 x86中-------------------- ...
- vue.js(15)--vue的生命周期
生命周期钩子 生命周期钩子=生命周期函数=生命周期事件 每个 Vue 实例在被创建时都要经过一系列的初始化过程——例如,需要设置数据监听.编译模板.将实例挂载到 DOM 并在数据变化时更新 DOM 等 ...
- CogniViewPDF2XL——将PDF表格转化为Excell表的软件
1. 下载官网地址:http://www.cogniview.com/download 2. 安装完后的样子