[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 ...
随机推荐
- Java 之 回调方法
打个比方,我们点外卖都有到达提醒的服务,顾客自己选择提醒的方式.可以是电话提醒.短信提醒.也可以敲门提醒,这里,“提醒”这个行为是美团或饿了么这样的平台提供的,相当于库函数,但是提醒的方式是由顾客决定 ...
- Dynamic Programming and Policy Evaluation
Dynamic Programming divides the original problem into subproblems, and then complete the whole task ...
- vue 父子component生命周期
如今前端框架都流行组件化,页面元素都可以使用组件进行高度概括,那么处理组件之间的关系就如同处理页面架构一样重要.正确理解组件之间的关系,才能让代码按照我们与预料方式工作.最近参与了一个Vue.js的项 ...
- ubuntu彩色图形界面
Ubuntu的默认 ~/.bashrc 文件里,有一个控制是否打开彩色提示符文件的变量 $force_color_promt,只需要打开这个变量的开关,就可以使用彩色的命令行提示符了. 这对于输查看命 ...
- FormData模拟表单上传图片
[node]---multer模块实现图片上传---FORMDATA 1.安装muterl第三方模块 cnpm install multer --save 2.使用 multer在解析完成后,会向 ...
- MongoDB 基本操作(增改删)
1.插入数据 和关系型数据库一样,增加数据记录可以使用insert语句,这是很简单的. 当插入数据时,如果此集合不存在,则MongoDB系统会自动创建一个集合,即不需要刻意预先创建集合 每次插入数据时 ...
- dfs(魔力转圈圈)
http://oj.jxust.edu.cn/contest/problem?id=1563&pid=4 题目描述 Storm有一个m行n列的整数矩阵. 他会从(1,1)开始,顺时针螺旋访问该 ...
- java 继承extends 的相关知识点
java只有单继承,不能多继承 子类只能继承父类的非私有成员(成员变量.成员方法) 子类不能继承父类的构造方法,但是可以通过super关键字访问父类的构造方法 继承 要体现子类父类的 继承关系, ”i ...
- 小白学Python(9)——pyecharts 绘制漏斗图 Funnel
根据pyecharts的介绍一直没有研究明白def和return的用法,无法显示完整的漏斗图,还请各位指点. 根据上文绘制bar的方法,我更改了代码,做出了漏斗图,不过和demo不一样,而且数据也会随 ...
- mysql 可重复读
概念 Repeatable Read(可重复读):即:事务A在读到一条数据之后,此时事务B对该数据进行了修改并提交,那么事务A再读该数据,读到的还是原来的内容. 实现原理(MVCC [ 多版本并发控制 ...