图像有用区域
时间限制:3000 ms | 内存限制:65535 KB
难度:4
- 描述
“ACKing”同学以前做一个图像处理的项目时,遇到了一个问题,他需要摘取出图片中某个黑色线圏成的区域以内的图片,现在请你来帮助他完成第一步,把黑色线圏外的区域全部变为黑色。
图1 图2
已知黑线各处不会出现交叉(如图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
#include<iostream>
#include<vector>
#include<cstdio>
#include<queue>
using namespace std;
vector< int > vec[10000];
int s1[4]={0,1,0,-1};//广搜,在此处定义方向向量,
int s2[4]={1,0,-1,0};
struct node {
int x; // 坐标
int y;
}t;
vector < node > q; //用队列,或者用数组也行
int main()
{
int n,m,k,a;
scanf("%d",&k);
while(k--)
{
while(q.size())
{
q.pop_back();
}
for(int i=0;i<10000;i++)
vec[i].clear();
q.clear();
scanf("%d%d",&m,&n);
int t1=0;
for(int i=0;i<n;i++)
{
for(int j=0;j<m;j++){
scanf("%d",&a);
vec[i].push_back(a);
}
}
for(int i=0;i<n;i++)//对矩阵的第一列和最后一列进行处理
{
if(vec[i][0]!=0){
t.x=i;
t.y=0;
q.push_back(t);
vec[i][0]=0;
}
if(vec[i][m-1]!=0){
t.x=i;
t.y=m-1;
q.push_back(t);
vec[i][m-1]=0;
}
}
for(int i=0;i<m;i++)//对矩阵的第一列和最后一列进行处理。
{
if(vec[0][i]!=0){
t.x=0;
t.y=i;
q.push_back(t);
vec[0][i]=0;
}
if(vec[n-1][i]!=0){
t.x=n-1;
t.y=i;
q.push_back(t);
vec[n-1][i]=0;
}
}
cout<<endl;
while(q.empty()==0)
{
int x1,y1;
node a=q.back();//一定要定义在for循环外面定义在里面,第一次循环就删除了队列的第一个元素。
q.pop_back();
for(int i=0;i<4;i++)
{
x1=s1[i]+a.x;
y1=s2[i]+a.y;
if(x1<0 || x1>=n || y1<0 || y1>=m)
continue;
if(vec[x1][y1]!=0)
{
t.x=x1;
t.y=y1;
q.push_back(t);
vec[x1][y1]=0;
}
}
}
for(int i=0;i<n;i++)
{
for(int j=0;j<m;j++)
{
printf("%d",vec[i][j]);
printf(" ");
}
cout<<endl;
}
}
}