图像有用区域
时间限制:
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
-
第一行输入测试数据的组数N(0<N<=6)
这个可以说只在NYOJ上遇到的最令我纠结的一道题了。为了它付出的那么多天的时间,真是纠结的要摔头啊!!!
其实这道题也不难,看到的第一次就直接写出来了,就是一直内存超限,就是因为元素入队列与标记的顺序颠倒了。然后就是各种改啊。。。。
#include<cstdio>
#include<cstring>
#include<iostream>
#include<queue>
using namespace std;
const int W=1450,H=970;
int w,h,a[H][W];
int dx[4]={0,0,1,-1},dy[4]={-1,1,0,0};
void bfs(int x,int y)
{
a[x][y]=0;
queue<int> q;
q.push(x);
q.push(y);
while(!q.empty())
{
x=q.front();
q.pop();
y=q.front();
q.pop();
for(int i=0;i<4;i++)
{
int nx=x+dx[i];
int ny=y+dy[i];
if(nx>=0&&nx<h+2&&ny>=0&&ny<w+2&&a[nx][ny])
{
a[nx][ny]=0; //先将元素标记为黑色,然后加入队列
q.push(nx); //如果先加入队列,然后每次出队列的时候将其标记为黑色
q.push(ny); //就会重复遍历图中的一些元素,数据一大重复的规模就相当大了
} //然后内存超限。。。。
}
}
}
int main()
{
int t;
scanf("%d",&t);
while(t--)
{
scanf("%d%d",&w,&h);
int i,j;
memset(a,-1,sizeof(a));
for(i=1;i<h+1;i++)
for(j=1;j<w+1;j++)
scanf("%d",&a[i][j]);
bfs(0,0);
for(i=1;i<h+1;i++)
{
for(j=1;j<w+1;j++)
printf("%d ",a[i][j]);
printf("\n");
}
}
return 0;
}
如果使用标记数组的话,应该就不会出现这种情况。使用队列时没有考虑太多,给自己的教训真不小。。。