【CCF 201909-3】字符画(学习IO)

本题的思路不算难,但是需要快速完成需要对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;
}
发布了91 篇原创文章 · 获赞 142 · 访问量 9万+

猜你喜欢

转载自blog.csdn.net/leelitian3/article/details/104107202