题目
黑白图片存储有两种格式:位图格式和压缩格式;
位图格式:使用一个矩阵(元素为01)来表示一个黑白图片;
压缩格式:图像是单一颜色(全都是0或1),则图像为对应的值(0或1),否则图像的值为D,并将图形分成四个矩形(不能平均分时左侧和上侧多取一个像素),分别判断四个子图像,按照从上到下、从左到右的顺序组成一个字符串;
现在已知两种格式的某一种,需要转化到另一种;
分析
将两种转化分为两个过程,分别利用递归求解。
位图格式转化到压缩格式:先利用DP求解出每个矩形中的1的总和,然后利用面积可以快速判断,子图形是否只有一个颜色,然后递归计算四个子区域;
压缩格式转化到位图格式:如果是D利用递归求解,如果不是D则染色即可;
说明
注意数据格式,每行最多50个字符。
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
char Dmaps[40404];
int Dmaps_count = 0;
int line[202][202] = {0}, sum[202][202] = {0};
void B2D(int r1, int r2, int c1, int c2)
{
int ones = sum[r2][c2] - sum[r1-1][c2] - sum[r2][c1-1] + sum[r1-1][c1-1];
int area = (r2-r1+1)*(c2-c1+1);
if (ones == 0 || ones == area) {
Dmaps[Dmaps_count ++] = ones/area + '0';
return;
}
if (r1 == r2 && c1 == c2) {
Dmaps[Dmaps_count ++] = ones/area + '0';
return;
}
Dmaps[Dmaps_count ++] = 'D';
int mid_row = (r1 + r2)/2;
int mid_col = (c1 + c2)/2;
B2D(r1, mid_row, c1, mid_col); // block1
if (mid_col < c2) {
B2D(r1, mid_row, mid_col+1, c2); // block2
}
if (mid_row < r2) {
B2D(mid_row+1, r2, c1, mid_col); // block3
if (mid_col < c2) {
B2D(mid_row+1, r2, mid_col+1, c2); // block4
}
}
}
char Bmaps[40404];
int Dmaps_point = 0;
void D2B(int r1, int r2, int c1, int c2, int column)
{
if ('D' != Dmaps[Dmaps_point]) {
for (int i = r1; i <= r2; ++ i) {
for (int j = c1; j <= c2; ++ j) {
Bmaps[i*column + j] = Dmaps[Dmaps_point];
}
}
Dmaps_point ++;
}else {
Dmaps_point ++;
int mid_row = (r1 + r2)/2;
int mid_col = (c1 + c2)/2;
D2B(r1, mid_row, c1, mid_col, column); // block1
if (mid_col < c2) {
D2B(r1, mid_row, mid_col+1, c2, column); // block2
}
if (mid_row < r2) {
D2B(mid_row+1, r2, c1, mid_col, column); // block3
if (mid_col < c2) {
D2B(mid_row+1, r2, mid_col+1, c2, column); // block4
}
}
}
}
char buf[100], data[40404];
void image_input()
{
data[0] = 0;
while (1) {
gets(buf);
int blank = 0;
for (int i = 1; buf[i]; ++ i) {
if (' ' == buf[i]) {
blank = i;
break;
}
}
int letter = 0;
for (int i = blank; buf[i]; ++ i) {
if (' ' != buf[i]) {
letter = i;
break;
}
}
if ('#' == buf[0] || blank && letter) {
return;
}
strcat(data+strlen(data), buf);
}
}
int main()
{
char type;
int row, column;
gets(buf);
while ('#' != buf[0]) {
sscanf(buf, "%c %d %d", &type, &row, &column);
image_input();
if ('B' == type) {
strcpy(Bmaps, data);
for (int i = 1; i <= row; ++ i) {
for (int j = 1; j <= column; ++ j) {
line[i][j] = line[i][j-1] + Bmaps[(i-1)*column + j-1] - '0';
sum[i][j] = sum[i-1][j] + line[i][j];
}
}
Dmaps_count = 0;
B2D(1, row, 1, column);
printf("D%4d%4d\n%", row, column);
for (int i = 0; i < Dmaps_count; ++ i) {
if (i && i%50 == 0) {
printf("\n");
}
printf("%c", Dmaps[i]);
}
printf("\n");
}else {
strcpy(Dmaps, data);
Dmaps_point = 0;
D2B(0, row-1, 0, column-1, column);
int Bmaps_count = row*column;
printf("B%4d%4d\n%", row, column);
for (int i = 0; i < Bmaps_count; ++ i) {
if (i && i%50 == 0) {
printf("\n");
}
printf("%c", Bmaps[i]);
}
printf("\n");
}
}
return 0;
}