图像有用区域 时间限制:3000 ms | 内存限制:65535 KB 难度:4 描述 “ACKing”同学以前做一个图像处理的项目时,遇到了一个问题,他需要摘取出图片中某个黑色线圏成的区域以内的图片,现在请你来帮助他完成第一步,把黑色线圏外的区域全部变为黑色。
已知黑线各处不会出现交叉(如图2),并且,除了黑线上的点外,图像中没有纯黑色(即像素为0的点)。
输入 第一行输入测试数据的组数N (0<N<=6) 每组测试数据的第一行是两个个整数W,H分表表示图片的宽度和高度(3<=W<=1440,3<=H<=960) 随后的H行,每行有W个正整数,表示该点的像素值。(像素值都在0到255之间,0表示黑色,255表示白色) 输出 以矩阵形式输出把黑色框之外的区域变黑之后的图像中各点的像素值。 样例输入 1 5 5 100 253 214 146 120 123 0 0 0 0 54 0 33 47 0 255 0 0 78 0 14 11 0 0 0 样例输出 0 0 0 0 0 0 0 0 0 0 0 0 33 47 0 0 0 0 78 0 0 0 0 0 0
思路: 运用bfs处理,遇到非零就压入队列,遇到零就忽略掉。
这里有几点需要注意: 1. 从哪一个点开始,如果第一排 也就是如何处理这种情况 5 5 0 0 0 0 0 0 9 9 0 1 0 0 0 0 2 1 1 1 1 2 1 1 1 1 1 2. 若有某行全零,该怎么处理 5 5 1 1 1 1 1 0 0 0 0 0 0 9 9 9 0 0 0 0 0 0 1 1 1 1 1
处理以上两种问题方法: 把输入的矩阵外围用全1圈住即可 3. 注意题目中行宽的顺序
#include<iostream> #include<cstdio> #include<queue> #include<cstring> using namespace std; typedef struct{ int x; int y; }node; int N; int W,H; int a[1440][1440]; int way[4][4]={{-1,0},{0,1},{1,0},{0,-1}}; void BFS(int x,int y) { queue<node> q; node head; head.x=x; head.y=y; q.push(head); while(!q.empty()) { node pr=q.front(); q.pop(); if(a[pr.x][pr.y]!=0) { a[pr.x][pr.y]=0; node next; for(int i=0;i<4;i++)//4个方向 { next.x=pr.x+way[i][0]; next.y=pr.y+way[i][1]; if( next.x<=H+1 && next.x>=0 && next.y<=W+1 && next.y>=0 && a[next.x][next.y]!=0)//注意这里x的范围是0~H+1 ,y的范围是0~W+1 ,因为要把外面全1的圈考虑进去。 { q.push(next); } } } } for(int i=1;i<=H;i++) { for(int j=1;j<=W;j++) printf("%d ",a[i][j]); printf("\n"); } } int main() { scanf("%d",&N); for(int i=0;i<N;i++) { memset(a,1,sizeof(a));//将矩阵的外围全部赋值为1 scanf("%d%d",&W,&H); for(int j=1;j<=H;j++) { for(int k=1;k<=W;k++) { scanf("%d",&a[j][k]); } } //从0,0 开始,这样就不会一开始就遇到0了 BFS(0,0); } return 0; }