【JZOJ5769】引子

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";
}

猜你喜欢

转载自blog.csdn.net/qq_41513352/article/details/81488660