洛谷 P1162 填涂颜色题解

题目描述

由数字00组成的方阵中,有一任意形状闭合圈,闭合圈由数字11构成,围圈时只走上下左右44个方向。现要求把闭合圈内的所有空间都填写成22.例如:6 \times 66×6的方阵(n=6n=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(1 \le n \le 30)n(1n30)

接下来nn行,由00和11组成的n \times nn×n的方阵。

方阵内只有一个闭合圈,圈内至少有一个00。

//感谢黄小U饮品指出本题数据和数据格式不一样. 已修改(输入格式)

输出格式

已经填好数字22的完整方阵。

输入输出样例

输入 #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 \le n \le 301n30


 

题解

这道题有一个简单的算法就是输入时将所有为0的数据都填写为2,然后从4个边向内部进行BFS,如果搜索到2就将其改为0,并继续搜索,如果搜索到1或0就停止搜索。

  1 #include <iostream>
  2 #include <stdio.h>
  3 #include <math.h>
  4 #include <algorithm>
  5 #include <string.h>
  6 
  7 using namespace std;
  8 
  9 const int MAXN = 105;
 10 int n, map[MAXN][MAXN], vis[MAXN][MAXN];
 11 int pos[4][2] = {0, 1, 0, -1, 1, 0, -1, 0};
 12 
 13 struct Node
 14 {
 15     int x, y;
 16 };
 17 
 18 Node q[MAXN];
 19 int front, rear;
 20 int a, b;
 21 
 22 void bfs()
 23 {
 24     Node now;
 25     now.x = a;
 26     now.y = b;
 27     if(map[a][b] != 2)
 28     {
 29         return;
 30     }
 31     front = rear = 0;
 32     q[rear] = now;
 33     rear++; 
 34     while(front < rear)
 35     {
 36         now = q[front++]; 
 37         if(map[now.x][now.y] == 2)
 38         {
 39             map[now.x][now.y] = 0;
 40         }
 41         if(now.x == 7)
 42         {
 43             now.x = 7;
 44         }
 45         for(int i = 0; i < 4; i++) 
 46         {
 47             int nx = now.x + pos[i][0]; 
 48             int ny = now.y + pos[i][1]; 
 49             if(nx <= n && nx > 0 && ny <= n && ny > 0  
 50                 && vis[nx][ny] == false 
 51                 && map[nx][ny] == 2) 
 52             {
 53                 map[nx][ny] = 0;
 54                 vis[nx][ny] = true;
 55                 q[rear].x = nx;
 56                 q[rear].y = ny;
 57                 rear++;
 58             }
 59         } 
 60     }
 61 }
 62 
 63 
 64 int main()
 65 {
 66     cin >> n;
 67     for(int i = 1; i <= n; i++)
 68     {
 69         for(int j = 1; j <= n; j++)
 70         {
 71             cin >> map[i][j];
 72             if(map[i][j] == 0)
 73             {
 74                 map[i][j] = 2;
 75             }
 76         }
 77     }
 78     for(int i = 1; i <= n; i++)
 79     {
 80         a = 1;
 81         b = i;
 82         bfs();
 83     }
 84     for(int i = 1; i <= n; i++)
 85     {
 86         a = n;
 87         b = i;
 88         bfs();
 89     }
 90     for(int i = 1; i <= n; i++)
 91     {
 92         a = i;
 93         b = 1;
 94         bfs();
 95     }
 96     for(int i = 1; i <= n; i++)
 97     {
 98         a = i;
 99         b = n;
100         bfs();
101     }
102     for(int i = 1; i <= n; i++)
103     {
104         for(int j = 1; j <= n; j++)
105         {
106             cout << map[i][j] << " ";
107         }
108         cout << endl;
109     }
110     return 0;
111 }

这个BFS并不难写,不过当时犯了一个小错误,导致2/3/4个样例都是WA,特别是第2个样例在本机输出的结果和标准答案一致,但是提交后总是说一个位置应该为0,输出了2。查了很久,最后发现是把pos[4][2]写成了pos[2][4]。数组定义错了,导致遍历时移动的位置错误了,而且本机的对应内存的数据和测试机不同,所以在本机上是过了,但是测试机没有过。

转载于:https://www.cnblogs.com/zealsoft/p/11404420.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值