P1162 填涂颜色
题目描述
由数字0 组成的方阵中,有一任意形状闭合圈,闭合圈由数字1构成,围圈时只走上下左右4个方向。现要求把闭合圈内的所有空间都填写成2.例如:6X6的方阵(n=6),涂色前和涂色后的方阵如下:
0 0 0 0 0 0 0 0 1 1 1 1 0 1 1 0 0 1 1 1 0 0 0 1 1 0 0 0 0 1 1 1 1 1 1 1
0 0 0 0 0 0 0 0 1 1 1 1 0 1 1 2 2 1 1 1 2 2 2 1 1 2 2 2 2 1 1 1 1 1 1 1
输入输出格式
输入格式:
每组测试数据第一行一个整数:n。其中n(1<=n<=30)
接下来n行,由0和1组成的nXn的方阵。
方阵内只有一个闭合圈,圈内至少有一个0。
//感谢黄小U饮品指出本题数据和数据格式不一样. 已修改(输入格式)
输出格式:
已经填好数字2的完整方阵。
输入输出样例
输入样例#1:
6 0 0 0 0 0 0 0 0 1 1 1 1 0 1 1 0 0 1 1 1 0 0 0 1 1 0 0 0 0 1 1 1 1 1 1 1
输出样例#1:
0 0 0 0 0 0 0 0 1 1 1 1 0 1 1 2 2 1 1 1 2 2 2 1 1 2 2 2 2 1 1 1 1 1 1 1
说明
1<=n<=30
还是bfs解。
思路是先把所有的0都涂色成2
然后再判断2有木有靠着边界的连通块
有就都涂色成0 因为靠着边界,那么这个连通块肯定没被1围住
1 #include <cstdio> 2 3 int map[40][40]; 4 char book[40][40]; 5 struct node 6 { 7 int x, y; 8 }que[905]; 9 int move[4][2] = {{0,1},{0,-1},{1,0},{-1,0}}; 10 11 12 int main() 13 { 14 int n, tmp, head, tail; 15 scanf("%d", &n); 16 for(int i=1; i<=n; i++) 17 for(int j=1; j<=n; j++) 18 { 19 scanf("%d", &tmp); 20 if(tmp == 1) 21 { 22 map[i][j] = 1; 23 book[i][j] = 1; //标记不能走 24 } 25 else 26 map[i][j] = 2; //0涂色成2 27 } 28 29 30 for(int i=1; i<=n; i++) 31 for(int j=1; j<=n; j++) 32 { 33 //如果是2 34 if(map[i][j] == 2) 35 { 36 int flag = 0; 37 head = tail = 1; //注意这里 38 que[tail].x = i; 39 que[tail].y = j; 40 tail++; 41 while(head<tail) 42 { 43 int nx, ny; 44 for(int k=0; k<4; k++) 45 { 46 nx = que[head].x + move[k][0]; 47 ny = que[head].y + move[k][1]; 48 if(nx && ny && nx<=n && ny<=n && !book[nx][ny]) 49 { 50 que[tail].x = nx; 51 que[tail].y = ny; 52 tail++; 53 book[nx][ny] = 1; 54 } 55 //如果出了边界 那就说明这个2靠边界 那就标记 56 else if(nx<1 || nx>n || ny<1 || ny>n) 57 flag = 1; 58 } 59 head++; 60 } 61 //如果标记了 那就把刚刚的连通块涂色成0 62 if(flag) 63 for(int k=1; k<tail; k++) 64 map[que[k].x][que[k].y] = 0; 65 } 66 } 67 68 //注意输入格式 69 for(int i=1; i<n; i++) 70 { 71 for(int j=1; j<n; j++) 72 printf("%d ", map[i][j]); 73 printf("%d\n", map[i][n]); 74 } 75 for(int j=1; j<n; j++) 76 printf("%d ", map[n][j]); 77 printf("%d", map[n][n]); 78 79 return 0; 80 }
时间: 2024-10-03 07:47:11