http://www.pipioj.online/problem.php?id=1033
题目描述
PiPi喜欢把别人的名字拆开来,比如“螺”就可以拆成“虫田糸”,PiPi的语文学的不是很好,于是她决定使用编程的方式来解决这个问题。
给出一个01矩阵,1占据的部分即为需要拆的字,如果两个1分享一条边,那么它们连通。连通具有传递性,即如果a、b连通,b、c连通,则a、c连通。
连通的一系列1被看做可以拆出的一块,现在PiPi需要输出这些拆出的块(用一个01矩阵表示,并且要求矩阵的大小尽可能的小)。
为了确保输出的顺序尽可能的和书写的顺序一致,PiPi从每个块中选出最左上角的点(最左侧的点中,最靠上的)作为代表点,然后按照代表点从左到右(若相同则按从上到下)的顺序输出所有拆出的块。
输入
多组数据。
输入的第一行为两个正整数N、M,表示01矩阵的大小。
接下来N行,每行M个01字符,描述一个需要拆的字。
对于40%的数据,满足1<=N,M<=10。
对于100%的数据,满足1<=N,M<=500。
额外的样例:
11 17
00000000000000000
00001111111100000
00000000000000000
00111111111111100
00000000100000000
00000010101110000
00000110100011000
00011100100001000
00000010100000000
00000001100000000
00000000000000000
输出
按照代表点从左到右(若相同则按从上到下)的顺序输出所有拆出的块。
对于每个块,先输出其大小,然后用对应的01矩阵表示这个块。
7 13
1111111111111
0000001000000
0000001000000
0000001000000
0000001000000
0000001000000
0000011000000
3 4
0001
0011
1110
1 8
11111111
1 1
1
3 4
1110
0011
0001
样例输入
14 22
0000000000001111111100
0000000000001101101100
0000110000001111111100
0000110000001101101100
0111111110001111111100
0110110110000000000000
0110110110000011000000
0111111110001111111000
0000110000000001100000
0000110110001111111100
0111111111000111111000
0000000010001101101100
0000000000000001100000
0000000000000011100000
样例输出
10 9
000110000
000110000
111111110
110110110
110110110
111111110
000110000
000110110
111111111
000000010
5 8
11111111
11011011
11111111
11011011
11111111
8 8
00110000
11111110
00011000
11111111
01111110
11011011
00011000
00111000
提示
PIPI:大家还记得联通分量这个概念吧~
#include <iostream>
#include <stdio.h>
#include <stdlib.h>
#include <queue>
using namespace std;
int N,M;
int matrix[505][505];
int visited[505][505];
char c[505];
int dir[4][2]={{0,1},{0,-1},{1,0},{-1,0}};
int minx,maxx,miny,maxy,n;
void dfs(int x,int y){
int i,xx,yy;
for(i=0;i<4;i++){
xx=x+dir[i][0];
yy=y+dir[i][1];
if(xx>=0&&xx<N&&yy>=0&&yy<M&&!visited[xx][yy]&&matrix[xx][yy]){
minx=minx>xx?xx:minx;
maxx=maxx>xx?maxx:xx;
miny=miny>yy?yy:miny;
maxy=maxy>yy?maxy:yy;
visited[xx][yy]=n;
dfs(xx,yy);
}
}
}
int main(){
int i,j,k,l;
while(scanf("%d %d",&N,&M)!=EOF){
n=1;
for(i=0;i<N;i++){
scanf("%s",c);
for(j=0;j<M;j++){
if(c[j]=='0') matrix[i][j]=0;
else if(c[j]=='1') matrix[i][j]=1;
visited[i][j]=0;}
}
for(i=0;i<M;i++)
for(j=0;j<N;j++)
if(!visited[j][i]&&matrix[j][i]==1){
visited[j][i]=n;
minx=maxx=j;
maxy=miny=i;
dfs(j,i);
printf("%d %d\n",maxx-minx+1,maxy-miny+1);
for(k=minx;k<=maxx;k++){
for(l=miny;l<=maxy;l++)
if(visited[k][l]==n) printf("1");
else printf("0");
printf("\n");}
n++;
}
}//while
}
来源:CSDN
作者:宅宅宅宅
链接:https://blog.csdn.net/qq_41646522/article/details/104877058