timus_1006

正方形框

   这道题目比较有意思,它在屏幕上给出了一张画有一些正方形方框的图形,这些方框可能互相覆盖,但不会超出屏幕的边界。现有要求你给出一个能构成该图形的方框序列。这些方框可以由下列字符组成:

  

  输入:一张画有正方形框的图

  输出:

  K
  X1 Y1 A1
  …
  Xk Yk Ak

  K代表正方框的数量,X和Y代表正方形的左上角坐标,A代表正方形的长度

  样例输入:

  

  样例输出:

  6
  16 11 7
  32 14 4
  4 8 8
  11 6 7
  36 11 3
  28 8 3

程序代码:
  1 #include <stdio.h>
  2 
  3 unsigned char map[50][20];//记录屏幕中框的情况
  4 unsigned char screen[20][50];
  5 typedef struct _frame_t
  6 {
  7     int left;//左上角的横坐标
  8     int top;//左上角的纵坐标
  9     int width;//宽度
 10 }frame_t;
 11 
 12 #define MAX_FRAME_SIZE 2000
 13 #define min(a, b) (a > b ? b : a)
 14 frame_t frame[MAX_FRAME_SIZE + 1]; 
 15 int n;
 16 
 17 #define MAX_FRAME 16
 18 
 19 //#define DEBUG 
 20 #ifdef DEBUG
 21 #define PRINT() Print()
 22 #else 
 23 #define PRINT()
 24 #endif
 25 
 26 void Print()
 27 {
 28     int i, j;
 29 
 30     for (i = 0; i < 20; i ++)
 31     {
 32         for (j = 0; j < 50; j ++)
 33                 printf("%c ", (map[j][i] ? map[j][i] : '1'));
 34         printf("\n");
 35     }
 36     printf("\n");
 37 }
 38 int IsFrame(int left, int top, int len)
 39 {
 40     int i;
 41 
 42     for (i = 1; i < len - 1; i ++)
 43     {
 44         if (!(map[left + i][top] == 196 || map[left + i][top] == 0))    
 45             return 0;
 46         if (!(map[left + i][top + len - 1] == 196 || map[left + i][top + len - 1] == 0))
 47             return 0;
 48         if (!(map[left][top + i] == 179 || map[left][top + i] == 0))
 49             return 0;
 50         if (!(map[left + len - 1][top + i] == 179 || map[left + len - 1][top + i] == 0))
 51             return 0;
 52     }
 53     if (!(map[left][top] == 218 || map[left][top] == 0))
 54         return 0;
 55     if (!(map[left + len - 1][top] == 191 || map[left + len - 1][top] == 0))
 56         return 0;
 57     if (!(map[left][top + len - 1] == 192 || map[left][top + len - 1] == 0))
 58         return 0;
 59     if (!(map[left + len - 1][top + len - 1] == 217 || map[left + len - 1][top + len - 1] == 0))
 60         return 0;
 61     return 1;
 62 }
 63 void ReduceFrame(int left, int top, int width)
 64 {
 65     int i;
 66 
 67     for (i = 0; i < width; i ++)
 68         map[left][top + i] = map[left + i][top] = map[left + width - 1][top + i] = map[left + i][top + width - 1] = 0;
 69 }
 70 
 71 int Search(int left, int top)
 72 {
 73     int i, j, len, count = 0;
 74     frame_t temp;
 75 
 76     if (map[left][top] == 196)        
 77     {
 78         //
 79         i = 1;
 80         while (i < MAX_FRAME && left - i >= 0 && map[left - i][top] != 46)
 81         {
 82             len = min(MAX_FRAME , min(50 - (left - i), 20 - top));    
 83             while (len >= 2)
 84             {
 85                 if (IsFrame(left - i, top, len))
 86                 {
 87                     ReduceFrame(left - i, top, len);    
 88                     frame[n].left = left - i;
 89                     frame[n].top = top;
 90                     frame[n ++].width = len;
 91                     PRINT();
 92                     return 1;
 93                 }
 94                 len --;
 95             }
 96             len = min(MAX_FRAME, min(50 - (left - i), top + 1));    
 97             while (len >= 2)
 98             {
 99                 if (IsFrame(left - i, top - len + 1, len))    
100                 {
101                     ReduceFrame(left - i, top - len + 1, len);    
102                     frame[n].left = left - i;
103                     frame[n].top = top - len + 1;
104                     frame[n ++ ].width = len;
105                     PRINT();
106                     return 1;
107                 }
108                 len --;
109             }
110             i ++;
111         }
112     }
113     else if (map[left][top] == 179)
114     {
115         //
116         i = 1;
117         while (i <  MAX_FRAME && top - i >= 0 && map[left][top - i] != 46)
118         {
119             len = min(MAX_FRAME , min(50 - left, 20 - (top - i)));    
120             while (len >= 2)
121             {
122                 if (IsFrame(left, top - i, len))
123                 {
124                     ReduceFrame(left, top - i, len);    
125                     frame[n].left = left;
126                     frame[n].top = top - i;
127                     frame[n ++].width = len;
128                     PRINT();
129                     return 1;
130                 }
131                 len --;
132             }
133             len = min(MAX_FRAME , min(left + 1, 20 - (top - i)));    
134             while (len >= 2)
135             {
136                 if (IsFrame(left - len + 1, top - i, len))
137                 {
138                     ReduceFrame(left - len + 1, top - i, len);    
139                     frame[n].left = left - len + 1;
140                     frame[n].top = top - i;
141                     frame[n ++].width = len;
142                     PRINT();
143                     return 1;
144                 }
145                 len --;
146             }
147             i ++;
148         }
149     }
150     else if (map[left][top] == 218)
151     {
152         //
153         len = min(MAX_FRAME , min(50 - left, 20 - top));    
154         while (len >= 2)
155         {
156             if (IsFrame(left, top, len))
157             {
158                 ReduceFrame(left, top, len);    
159                 frame[n].left = left;
160                 frame[n].top = top;
161                 frame[n ++].width = len;
162                 PRINT();
163                 return 1;
164             }
165             len --;
166         }
167     }
168     else if (map[left][top] == 191)
169     {
170         //
171         len = min(MAX_FRAME , min(left + 1, 20 - top));    
172         while (len >= 2)
173         {
174             if (IsFrame(left - len + 1, top, len))
175             {
176                 ReduceFrame(left - len + 1, top, len);    
177                 frame[n].left = left - len + 1;
178                 frame[n].top = top;
179                 frame[n ++].width = len;
180                 PRINT();
181                 return 1;
182             }
183             len --;
184         }
185     }
186     else if (map[left][top] == 217)
187     {
188         //
189         len = min(MAX_FRAME, min(left + 1, top + 1));    
190         while (len >= 2)
191         {
192             if (IsFrame(left - len + 1, top - len + 1, len))    
193             {
194                 ReduceFrame(left - len + 1, top - len + 1, len);    
195                 frame[n].left = left - len + 1;
196                 frame[n].top = top - len + 1;
197                 frame[n ++ ].width = len;
198                 PRINT();
199                 return 1;
200             }
201             len --;
202         }
203 
204     }
205     else
206     {
207         //
208         len = min(MAX_FRAME, min(50 - left, top + 1));    
209         while (len >= 2)
210         {
211             if (IsFrame(left, top - len + 1, len))    
212             {
213                 ReduceFrame(left, top - len + 1, len);    
214                 frame[n].left = left;
215                 frame[n].top = top - len + 1;
216                 frame[n ++ ].width = len;
217                 PRINT();
218                 return 1;
219             }
220             len --;
221         }
222     }
223     return 0;
224 }
225 int main(void)
226 {
227     int i,j;
228     //输入数据
229     for (i = 0; i < 20; i ++)
230             scanf("%s", screen[i]);    
231     for (i = 0; i < 20; i ++)
232         for (j = 0; j < 50; j ++)
233             map[j][i] = screen[i][j];
234     PRINT();
235 begin:
236     for (j = 0; j < 20; j ++)
237         for (i = 0; i < 50; i ++)
238             if (!(map[i][j] == 46 || map[i][j] == 0 || map[i][j] == 196 || map[i][j] == 179) && Search(i, j))
239                 goto begin;
240 begin1:
241     for (j = 0; j < 20; j ++)
242         for (i = 0; i < 50; i ++)
243             if (!(map[i][j] == 46 || map[i][j] == 0) && Search(i, j))
244                 goto begin1;
245     printf("%d\n", n);
246     for (i = n - 1; i >= 0; i --)
247         printf("%d %d %d\n", frame[i].left, frame[i].top, frame[i].width);
248     return 0;
249 }

  程序的大概思路就是总是扫描屏幕,每次扫描都找到一个屏幕上最上面的方框,将它保持起来并从屏幕上删除这个方框,重复这个过程直到屏幕上没有了方框为止。程序235-239行是对扫描屏幕中方框的顶点,如果顶点所在的方框在最上面,就将这个方框直接保存起来,并且从新扫描这个屏幕,这样这个方框下面的被遮盖的方框就可以找出来了。第240-244行对应的是扫描屏幕中方框的边,如果边所在的方框在最上面,就将这个方框直接保存起来,并且从新扫描这个屏幕。第245-247行输出结果。Search函数主要是用来构造方框的顶点,这是对于不确定方框顶点的情况,或者是构造方框的长度,这是已经确定了方框的顶点的情况。IsFrame判断Search构造的方框是否是当前屏幕最上方的方框。ReduceFrame是用来去除屏幕中已经找到的方框。

原文地址:https://www.cnblogs.com/chengxuyuancc/p/3097233.html