【链接】:http://acm.nyist.net/JudgeOnline/problem.php?pid=92
【题目】:
图像有用区域
时间限制:
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)
【思路】:
简单的广搜题,思路也很简单,特殊情况:黑圈的边界也是图形的边界,为了不影响,考虑在给定图外加一圈1,这样就能从左上角0,0开始广搜,广搜的思路在理清一遍:BFS就是广度优先遍历,百度上有详解。自己的体会:大体上是从一个位置开始,然后把距离相同的位置遍历一次,并把符合要求的点装到一个队列里,不断的从这个队取出元素进行上面的判断,重复这样的过程,直到队列为空了,那么符合条件的点也就都遍历了。这道题目中遍历过后我们就直接把这个点标记为黑色(即赋值为0)就好了。
【代码】:
/* ***********************************************
Author :herongwei
Created Time :08-13 Sun 2017 18:58:23 PM CST
File Name :nyoj-92.cpp
************************************************ */
#include <stdio.h>
#include <string.h>
#include <iostream>
#include <algorithm>
#include <vector>
#include <queue>
#include <set>
#include <map>
#include <string>
#include <math.h>
#include <stdlib.h>
#include <time.h>
#include <numeric>
#include <limits>
using namespace std;
typedef long long LL;
const int maxn = 1e5+2333;
const int MOD = 1e9+7;
const LL inf = 0x3f3f3f3f;
const double eps= 1e-8;
const double pi = acos(-1.0);
int dir[4][2]= {{0, 1}, {0, -1}, {-1, 0}, {1, 0}}; //上下左右
int n,m,t,tot,cnt,ans,ret,tmp;
inline int read(){
int c=0,f=1;
char ch=getchar();
while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}
while(ch>='0'&&ch<='9'){c=c*10+ch-'0';ch=getchar();}
return c*f;
}
queue<int >que;
char char_mp[2333];
int int_mp[2333][2333];
int w,h;
void bfs(int s,int t){
int cur_x,cur_y;
int new_x,new_y;
que.push(s);/*当前点进队*/
que.push(t);
while(!que.empty()){
cur_x=que.front();que.pop();/*不断从队首取出满足条件的元素直至队列为空*/
cur_y=que.front();que.pop();
for(int i=0; i<4; ++i){ /*上下左右遍历*/
new_x=cur_x+dir[i][0];
new_y=cur_y+dir[i][1];
if(new_x>=0&&new_x<=h+1&&new_y>=0&&new_y<=w+1){ /*判断边界注意因为加了边所以new_x<=h+1*/
if(int_mp[new_x][new_y]==0) continue; /*遇到黑圈,因为题目已经说明除黑圈外无其他0点*/
int_mp[new_x][new_y]=0; /*赋值操作*/
que.push(new_x); /*将新元素压队*/
que.push(new_y);
}
}
}
}
int main(){
// freopen("in2.txt","r",stdin);
t=read();
while(t--){
while(!que.empty())que.pop();
w=read();h=read();
for(int i=0; i<2333; ++i) /*加边*/
for(int j=0; j<2333; ++j)int_mp[i][j]=1;
for(int i=1; i<=h; ++i)
for(int j=1; j<=w; ++j){
int_mp[i][j]=read();
}
bfs(0,0);/*从0,0广搜*/
for(int i=1; i<=h; ++i)
for(int j=1; j<=w; ++j){
if(j!=w) printf("%d ",int_mp[i][j]);
else printf("%d\n",int_mp[i][j]);
}
}
return 0;
}