本题的思路不算难,但是需要快速完成需要对C++的IO库比较熟悉。
本题用到的IO知识
/* 打印字符c对应的<转移字符> */
void out_char(char c)
{
// 16进制输出,大写字母,宽度2,填充0
cout << "\\x" << setiosflags(ios::uppercase) << setw(2) << setfill('0') << hex << int(c);
}
'\x45' 转义字符,表示ASCII码为0x45的字符
/* 16进制string 转 10进制int */
int hex2int(const string &str)
{
int result;
stringstream ss(str);
ss >> hex >> result; // 利用字符串流输入hex(方法正确,但会超时)
return result;
}
其它知识
// 二维vector的初始化
vector<vector<Pixel>> picture;
picture.assign(n, vector<Pixel>(m, Pixel(0, 0, 0)));
#include <cstdio>
#include <cstring>
#include <iomanip>
#include <iostream>
#include <sstream>
#include <vector>
using namespace std;
/* 像素类型 */
struct Pixel
{
int R, G, B;
Pixel(int a, int b, int c) : R(a), G(b), B(c) {}
bool operator==(const Pixel &a)
{
return R == a.R && G == a.G && B == a.B;
}
};
int m, n, p, q;
vector<vector<Pixel>> picture; // 整幅图片
Pixel last_pixel(0, 0, 0); // 上次的背景色
Pixel default_pixel(0, 0, 0); // 默认的背景色
/* 打印字符c对应的<转移字符> */
void out_char(char c)
{
// 16进制输出,大写字母,宽度2,填充0
cout << "\\x" << setiosflags(ios::uppercase) << setw(2) << setfill('0') << hex << int(c);
}
/* 打印<设置背景色为RGB的命令>对应的<转义序列> */
void set_bg(int R, int G, int B)
{
string str = "\x1b[48;2;" + to_string(R) + ";" + to_string(G) + ";" + to_string(B) + "m";
for (auto c : str)
out_char(c);
}
/* 打印<重置背景色>对应的<转义序列> */
void set_default()
{
string str = "\x1b[0m";
for (auto c : str)
out_char(c);
}
/* 16进制string 转 10进制int */
int hex2int(const string &str)
{
int result;
// stringstream ss(str);
// ss >> hex >> result; // 利用字符串流输入hex(方法正确,但会超时)
int digit[2];
for (int i = 0; i < 2; ++i)
{
if (islower(str[i]))
digit[i] = str[i] - 'a' + 10;
else if (isupper(str[i]))
digit[i] = str[i] - 'A' + 10;
else
digit[i] = str[i] - '0';
}
result = digit[0] * 16 + digit[1];
return result;
}
/* 解析html像素字符串 */
void set_color(Pixel &pixel, const string &color)
{
string r, g, b;
switch (color.length())
{
case 2: // #a
r = g = b = color.substr(1) + color.substr(1);
break;
case 4: // #abc
r = color.substr(1, 1) + color.substr(1, 1);
g = color.substr(2, 1) + color.substr(2, 1);
b = color.substr(3, 1) + color.substr(3, 1);
break;
default: // #abcdef
r = color.substr(1, 2);
g = color.substr(3, 2);
b = color.substr(5, 2);
break;
}
// 设置像素值
pixel.R = hex2int(r);
pixel.G = hex2int(g);
pixel.B = hex2int(b);
}
int main()
{
// 关闭同步,提高输入输出效率
ios::sync_with_stdio(false);
cin.tie(0);
cout.tie(0);
cin >> m >> n >> p >> q;
picture.assign(n, vector<Pixel>(m, Pixel(0, 0, 0)));
string color;
for (int i = 0; i < n; ++i)
{
for (int j = 0; j < m; ++j)
{
cin >> color;
set_color(picture[i][j], color);
}
}
for (int i = 0; i < n / q; ++i)
{
for (int j = 0; j < m / p; ++j)
{
Pixel cur_pixel(0, 0, 0); // 计算当前块的平均像素值
for (int x = i * q; x < (i + 1) * q; ++x)
{
for (int y = j * p; y < (j + 1) * p; ++y)
{
cur_pixel.R += picture[x][y].R;
cur_pixel.G += picture[x][y].G;
cur_pixel.B += picture[x][y].B;
}
}
cur_pixel.R /= p * q;
cur_pixel.G /= p * q;
cur_pixel.B /= p * q;
// 如果和上一次的像素值不一样
if (!(cur_pixel == last_pixel))
{
if (cur_pixel == default_pixel)
set_default();
else
set_bg(cur_pixel.R, cur_pixel.G, cur_pixel.B);
last_pixel = cur_pixel;
}
out_char(' ');
}
// 行尾判断是否需要重置
if (!(last_pixel == default_pixel))
set_default();
last_pixel = default_pixel;
out_char('\n');
}
return 0;
}