• 引子 题解


    题意

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

    数字i所在的矩形代表一个编号为i的水箱。

    1号水箱为水箱中枢,有水管连出。除了1号水箱外,其他水箱上方会接进来恰好一条水管,也可能有水管连出。

    连出的水管会从水箱侧面连出去,同一个水箱连出去的水管会在不同的行与侧面连接。每一条水管直接连接两个水箱,这意味着不会把水管分叉也不会出现水管交叉的情况。这样,从一个水箱流入另外一个水箱时,水管的走向始终保持行号增加或保持不变。
    水会源源不断地涌进1号水箱直到各个水箱水满为止。帮助Slavko计算出各个水箱装满的次序。

    输入

    输入会给你一个n*m的点阵,点阵字符的全集为{+,|,-,.}

    水箱:形状是矩形,四角有+符号,左右为|,上下为-,里面包含一个数字代表水箱的编号,如上图。

    管道:一条管道恰好连接两个不同的水箱,|表示管道竖直摆放,- 表示管道水平摆放,其中竖直的管道之间会连接起来,水平的管道会连接起来,+连接竖直和水平的管道(+的上下恰好其中一个为.一个为|,+的左右恰好其中一个为 . 一个为-)。
    其余位置用. 来填充。

    输入的第1行为两个正整数n,m。

    接下来n行描述点阵的信息,每行有m个字符。

    输出

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

    解析

    一道大模拟题,找水箱,把标号存下,存下四个顶点的坐标之后,再找每个编号,利用之前求出的四个顶点找与此水箱相连的水管,找到之后,再顺着水管一直走,注意这里一定要小心想清楚怎么打很容易出错,知道走到一个水箱的边框上,这个我们已经处理了,然后就返回这个水箱的编号,每做完一次就相当于找到了两个联通的水箱,遍历完回溯的时候输出编号就可以了。

    代码

    #include<bits/stdc++.h>
    using namespace std;
    struct node{
    	int x1,x2;
    	int y1,y2;
    }a[100000];
    const int N=1010;
    const int dir[2][2][2]={{{0,-1},{0,1}},{{-1,0},{1,0}}};
    int num[N][N],n,m;
    char mape[N][N];
    int find(int x,int y,int d1,int d2){
    	if(num[x][y])return num[x][y];
    	if(mape[x][y]=='+'){
    		int newd1=1-d1;
    		char ch=mape[x+dir[newd1][0][0]][y+dir[newd1][0][1]];
    		if(newd1==1&&ch=='|'||newd1==0&&ch=='-'){
    			return find(x+dir[newd1][0][0],y+dir[newd1][0][1],newd1,0);
    		}
    		else return find(x+dir[newd1][1][0],y+dir[newd1][1][1],newd1,1);
    	}
    	else return find(x+dir[d1][d2][0],y+dir[d1][d2][1],d1,d2);
    }
    void dfs(int now){
    	int x1=a[now].x1;
    	int x2=a[now].x2;
    	int y1=a[now].y1;
    	int y2=a[now].y2;
    	for(int i=x2;i>=x1;--i){
    		if(y1>1&&mape[i][y1-1]=='-') dfs(find(i,y1-1,0,0));
    		if(y2<m&&mape[i][y2+1]=='-') dfs(find(i,y2+1,0,1));
    	}
    	printf("%d
    ",now);
    }
    int main(){
    	scanf("%d %d",&n,&m);
    	for(int i=1;i<=n;++i){
    		scanf("%s",mape[i]+1);
    	}
    	for(int i=1;i<=n;++i){
    		for(int j=1;j<=m;++j){
    			if(!num[i][j]&&isdigit(mape[i][j])){
    				int nexts=j,data=mape[i][j]-48;
    				while(nexts<m&&isdigit(mape[i][nexts+1]))data=data*10+mape[i][++nexts]-48;
    				int x1=i,x2=i,y1=j,y2=j;
    				while(x1>1&&mape[x1][j]!='-') x1--;
    				while(y1>1&&mape[i][y1]!='|') y1--;
    				while(x2<n&&mape[x2][j]!='-') x2++;
    				while(y2<m&&mape[i][y2]!='|') y2++;
    				a[data]=node{x1,x2,y1,y2};
    				for(int ii=x1;ii<=x2;++ii){
    					for(int jj=y1;jj<=y2;++jj){
    						num[ii][jj]=data;
    					}
    				}
    			}
    		}
    	}
    	dfs(1);
    	return 0;
    } 
    
  • 相关阅读:
    搭建mongoDB 配置副本集 replSet
    关于erlang解析json数据
    互联网精准广告定向技术
    cmd 查看端口占用情况
    nutzboot dubbo zookeeper简单使用
    一些常用名词
    小程序video置顶
    html 5 video audio
    android webview 视频相关
    微信小程序
  • 原文地址:https://www.cnblogs.com/donkey2603089141/p/11414985.html
Copyright © 2020-2023  润新知