NYOJ92 图像有用区域

图像有用区域

时间限制: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 }
功不成,身已退
原文地址:https://www.cnblogs.com/dongsheng/p/2941309.html