题目描述
由数字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(1≤n≤30)
接下来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说明/提示
301≤n≤30
洛谷P1162
思路:因为从左到右从上到下第一个找到的1右下角的0一定在圈内,所以从i+1,j+1 开始bfs即可,用数组标记查询到圈内0的数就行了
#include <iostream>
#include <cstring>
#include <queue>
using namespace std;
struct node
{
int x,y,step;
};
int n,p[40][40],book[40][40];
int inext[4][2]= {{0,1},{1,0},{0,-1},{-1,0}};
void bfs(int x,int y)
{
int tx,ty;
queue<node> q;
q.push({x,y});
while(!q.empty())
{
node head=q.front();
q.pop();
for(int i=0; i<4; i++)
{
tx=head.x+inext[i][0],ty=head.y+inext[i][1];
if(tx<1||ty<1||tx>n||ty>n||book[tx][ty]==1||p[tx][ty]==1) continue;
book[tx][ty]=1;
q.push({tx,ty});
}
}
}
int main()
{
cin >> n ;
for(int i=1; i<=n; i++)
for(int j=1; j<=n; j++)
cin >> p[i][j];
memset(book,0,sizeof book);
int i,j,flag=0;
for(i=1; i<=n; i++)
{
for(j=1; j<=n; j++)
{
if(p[i][j]==1) flag=1;
if(flag==1) break;
}
if(flag==1) break;
}
book[i+1][j+1]=1;//一定要把这个点放进去
bfs(i+1,j+1);
for(int i=1; i<=n; i++)
{
for(int j=1; j<=n; j++)
{
if(book[i][j]==1&&p[i][j]==0)
cout << "2" << ' ';
else cout << p[i][j] << ' ';
}
cout << endl;
}
}