Description
网上冲浪时,Slavko被冲到了水箱里,水箱由上而下竖直平面。示意图如下:
数字i所在的矩形代表一个编号为i的水箱。
1号水箱为水箱中枢,有水管连出。除了1号水箱外,其他水箱上方会接进来恰好一条水管,也可能有水管连出。
连出的水管会从水箱侧面连出去,同一个水箱连出去的水管会在不同的行与侧面连接。每一条水管直接连接两个水箱,这意味着不会把水管分叉也不会出现水管交叉的情况。这样,从一个水箱流入另外一个水箱时,水管的走向始终保持行号增加或保持不变。
水会源源不断地涌进1号水箱直到各个水箱水满为止。帮助Slavko计算出各个水箱装满的次序。
Input
输入会给你一个n*m的点阵,点阵字符的全集为{+,|,-,.}
水箱:形状是矩形,四角有+符号,左右为|,上下为-,里面包含一个数字代表水箱的编号,如上图。
管道:一条管道恰好连接两个不同的水箱,|表示管道竖直摆放,- 表示管道水平摆放,其中竖直的管道之间会连接起来,水平的管道会连接起来,+连接竖直和水平的管道(+的上下恰好其中一个为.一个为|,+的左右恰好其中一个为 . 一个为-)。
其余位置用. 来填充。
输入的第1行为两个正整数n,m。
接下来n行描述点阵的信息,每行有m个字符。
Output
输出水箱被浸满的顺序,每行一个序号。
Sample Input
Input 1
12 13
..+--+.......
+-|..|.......
|.|.1|--+....
|.+--+..|....
|......+----+
+---+..|..2.|
....|..+----+
.+--+........
.|...........
+---+........
|.3.|........
+---+........
Input 2
8 10
..........
.......+-+
...+---|1|
...|...+-+
...|......
..+-+.....
..|2|.....
..+-+.....
Sample Output
Output 1
2
3
1
Output 2
2
1
Data Constraint
【数据范围】
70%的数据:1≤n,m≤100。
100%的数据满足:1≤n,m≤1000
Hint
【样例解释】
把输入粘贴到记事本上就一目了然了。
题解:
一道代码实现模拟题,代码量较多,来到纪中的第一天就给我留下了不好的印象
考试时打的其实是正解,只是没有处理编号是一位数以上的情况,就只拿了40分,完了之后下来考虑了这种情况就A掉了
我的思路是先用BFS预处理出每个水箱四个顶点的横纵坐标,然后我们从第一个水箱开始找
通过样例很容易发现,要我们求的是一个树上的DFS序。我们从1号水箱的底端查找,找到一个水管连出去,我们就顺着
这个水管用BFS或者DFS往下找,直到找到一个上面是‘|’,下面是‘-’的情况,就代表我们找到了一个水箱。
我们用BFS识别出这个水箱的编号,注意多位数处理,识别出之后,再对这个水箱调用递归,不断往下DFS查找,直到一个没有
儿子的水箱。1号水箱一定是最后被填满的,在最后输出一个1即可。
代码:
#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cstring>
#include<string>
#include<vector>
#include<climits>
#include<cmath>
#include<cctype>
#include<stack>
#define MAXA 1005
using namespace std;
struct Rx {
int x1,y1;
int x2,y2;
int x3,y3;
int x4,y4;
}Box[3005];
int n,m,flag,Deltax[10] = {0,0,1,-1,-1,1,1,-1},Deltay[10] = {1,-1,0,0,-1,1,-1,1};
int dx,dy,q[3][MAXA],Lastx,Lasty,temp,tempNum;
char Map[MAXA][MAXA];
bool vis[1001][1001];
vector<int> Ans;
stack<char> Num;
int WaterDown(int x,int y);
int Findidx(int x,int y);
void Solve(int idx) {
for(int i=Box[idx].x3;i>=Box[idx].x1;i--) {
if(Map[i][Box[idx].y3 - 1] == '-') {
Lastx = i;
Lasty = Box[idx].y3;
int tempAns = WaterDown(i,Box[idx].y3 - 1);
Solve(tempAns);
Ans.push_back(tempAns);
}
if(Map[i][Box[idx].y4 + 1] == '-') {
Lastx = i;
Lasty = Box[idx].y4;
int tempAns = WaterDown(i,Box[idx].y4 + 1);
Solve(tempAns);
Ans.push_back(tempAns);
}
}
}
int WaterDown(int x,int y) {
while(1) {
for(int i=0;i<4;i++) {
dx = x + Deltax[i];
dy = y + Deltay[i];
if(Map[x][y] == '|' && Map[dx][dy] == '-')
return Findidx(dx + 1,dy);
if((Map[dx][dy] == '-' || Map[dx][dy] == '+' || Map[dx][dy] == '|') && (dx != Lastx || dy != Lasty)) {
Lastx = x;
Lasty = y;
x = dx;
y = dy;
break;
}
}
}
}
int Findidx(int x,int y) {
if(isdigit(Map[x][y])) {
while(isdigit(Map[x][y]))
y--;
y++;
temp = 1;
tempNum = 0;
for(y;isdigit(Map[x][y]);y++)
Num.push(Map[x][y]);
while(!Num.empty()) {
tempNum += (Num.top() - '0') * temp;
Num.pop();
temp *= 10;
}
return tempNum;
}
memset(vis,0,sizeof(vis));
int head = 1,tail = 1;
q[1][tail] = x;
q[2][tail++] = y;
vis[x][y] = 1;
while(head != tail) {
x = q[1][head];
y = q[2][head++];
for(int i=0;i<4;i++) {
dx = x + Deltax[i];
dy = y + Deltay[i];
if(isdigit(Map[dx][dy])) {
while(isdigit(Map[dx][dy]))
dy--;
dy++;
temp = 1;
tempNum = 0;
for(dy;isdigit(Map[dx][dy]);dy++)
Num.push(Map[dx][dy]);
while(!Num.empty()) {
tempNum += (Num.top() - '0') * temp;
Num.pop();
temp *= 10;
}
return tempNum;
}
if(!vis[dx][dy] && Map[dx][dy] != '|' && Map[dx][dy] != '-') {
vis[dx][dy] = 1;
q[1][tail] = dx;
q[2][tail++] = dy;
}
}
}
}
void Find4Point(int idx,int x,int y) {
memset(vis,0,sizeof(vis));
int head = 1,tail = 1,tempx = x,tempy = y;
q[1][tail] = x;
q[2][tail++] = y;
vis[x][y] = 1;
while(head != tail) {
x = q[1][head];
y = q[2][head++];
for(int i=0;i<8;i++) {
dx = x + Deltax[i];
dy = y + Deltay[i];
if(Map[dx][dy] == '+') {
if(dx < tempx && dy < tempy) {
Box[idx].x1 = dx;
Box[idx].y1 = dy;
}
else if(dx < tempx && dy > tempy) {
Box[idx].x2 = dx;
Box[idx].y2 = dy;
}
else if(dx > tempx && dy < tempy) {
Box[idx].x3 = dx;
Box[idx].y3 = dy;
}
else if(dx > tempx && dy > tempy) {
Box[idx].x4 = dx;
Box[idx].y4 = dy;
}
continue;
}
if(!vis[dx][dy] && Map[dx][dy] != '|' && Map[dx][dy] != '-') {
vis[dx][dy] = 1;
q[1][tail] = dx;
q[2][tail++] = dy;
}
}
}
}
int main() {
freopen("clickbait.in","r",stdin);
freopen("clickbait.out","w",stdout);
ios::sync_with_stdio(false);
cin.tie(0);
cin >> n >> m;
for(int i=1;i<=n;i++)
for(int j=1;j<=m;j++)
cin >> Map[i][j];
for(int i=1;i<=n;i++)
for(int j=1;j<=m;j++)
if(isdigit(Map[i][j])) {
temp = 1;
tempNum = 0;
for(j;isdigit(Map[i][j]);j++)
Num.push(Map[i][j]);
j--;
while(!Num.empty()) {
tempNum += (Num.top() - '0') * temp;
Num.pop();
temp *= 10;
}
Find4Point(tempNum,i,j);
}
//cout << Box[16].x1 << " " << Box[16].y1;
Solve(1);
for(int i=0;i<Ans.size();i++)
cout << Ans[i] << endl;
cout << "1";
}