图像有用区域
时间限制: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
1 /* 2 代码一: 3 本来想着只要按行搜索,将任意两个不连续的0之间划定为所选择 4 的区域就行了,但是测试不对,后来想想,可能是忽略了一些特殊情况吧 5 以下是错误思路的代码: 6 7 #include <iostream> 8 9 using namespace std; 10 11 int a[970][1450]; 12 int main() 13 { 14 int T, w, h; 15 cin >> T; 16 while(T--) 17 { 18 cin >> w >> h; 19 for(int i = 0; i < h; ++i) 20 { 21 for(int j = 0; j < w; ++j) 22 cin >> a[i][j]; 23 } 24 for(int i = 0; i < h; ++i) 25 { 26 bool flag = false; 27 for(int j = 0; j < w; ++j) 28 { 29 if(a[i][j] == 0) 30 { 31 flag = !flag; 32 while(!a[i][++j]) // 跳过连续的0像素 33 { 34 if(j >= w) 35 break; 36 } 37 } 38 if(!flag) 39 a[i][j] = 0; 40 } 41 } 42 for(int i = 0; i < h; ++i) 43 { 44 for(int j = 0; j < w; ++j) 45 cout << a[i][j] << ' '; 46 cout << endl; 47 } 48 } 49 return 0; 50 } 51 */ 52 53 /* 54 代码二: 55 上网搜了搜,发现应该是广搜的题,理了一下思路,一气呵成, 56 哈哈,很长时间都没写搜索题了,纪念下。。 57 */ 58 #include <iostream> 59 #include <queue> 60 61 using namespace std; 62 63 struct point 64 { 65 int x; 66 int y; 67 }; 68 69 int w, h; 70 int map[970][1450]; 71 int dir[4][2] = {-1, 0, 0, 1, 1, 0, 0, -1}; 72 73 void BFS(int a, int b) 74 { 75 queue <point> q; 76 point t1, t2; 77 t1.x = a; 78 t1.y = b; 79 q.push(t1); 80 while(!q.empty()) 81 { 82 t1= q.front(); 83 q.pop(); 84 for(int i = 0; i < 4; ++i) 85 { 86 t2.x = t1.x + dir[i][0]; 87 t2.y = t1.y + dir[i][1]; 88 //边界判定,注意最后一个判定条件的顺序不能放在前边,否则可能溢出; 89 //而且必须将加的一圈1也要搜索到,这样才能保证不遗漏; 90 if(t2.x < 0 || t2.x > h+1 || t2.y < 0 || t2.y > w+1 || map[t2.x][t2.y] == 0) 91 continue; 92 map[t2.x][t2.y] = 0; 93 q.push(t2); 94 } 95 } 96 } 97 98 int main() 99 { 100 int T; 101 cin >> T; 102 while(T--) 103 { 104 cin >> w >> h; 105 //在图像的一圈加上 1,即令其为非黑即可, 106 //这样就能保证图像的一周都可以被遍历一遍,不会遗漏 107 for(int i = 0; i <= h; ++i) 108 map[i][0] = map[i][w + 1] = 1; 109 for(int j = 0; j <= w; ++j) 110 map[0][j] = map[h + 1][j] = 1; 111 112 for(int i = 1; i <= h; ++i) 113 for(int j = 1; j <= w; ++j) 114 cin >> map[i][j]; 115 BFS(0, 0); 116 for(int i = 1; i <= h; ++i) 117 for(int j = 1; j <= w; ++j) 118 { 119 if(j == w) 120 cout << map[i][j] << endl; 121 else 122 cout << map[i][j] << ' '; 123 } 124 } 125 return 0; 126 }