CSP认证字符画

tech2022-11-01  108

字符画

吐槽:

这个题的题目描述是真的狗,网上看了许多100分代码的博客讲解才弄懂。

题目大意:

前景色是干扰项,实际要用的是背景色题目所说的需要(mn)/(pq)个空格和n/q个换行,是每改变一个颜色打印一个空格,每打印一行打印一个换行,所以有(mn)/(pq)个空格和n/q个换行打印的是ASCII编码的十六进制表示,要用到双转义,即“\x”,比如:“\x31”在终端打印出来时1,“\x31”打印的才是\x31 #include <iostream> using namespace std; #include <string> #include <vector> #define ENTER "\\x0A" #define BLANK "\\x20" #define SEMICOLON "\\x3B" #define MM "\\x6D" #define BEFORE "\\x1B\\x5B\\x34\\x38\\x3B\\x32\\x3B" #define RESET "\\x1B\\x5B\\x30\\x6D" string base16(char c) { int num; string first, second; num = c; //获得字符的ASCII码 if (num/16 >= 10) { first = num/16 -10 + 'A'; } else { first = num/16 + '0'; } if (num%16 >= 10) { second = num%16 -10 + 'A'; } else { second = num%16 + '0'; } return first + second; } string to16Str(int num) { //字符ASCII码的16进制编码 string s, s1; int n; s = to_string(num); //将数字转换为字符串 for (int i=0; i<s.size(); ++i) { //求出字符串中各个字符的16进制ASCII编码 s1 += "\\x" + base16(s[i]); } return s1; } void printRGB(vector<int> v) { string s; for (int i=0; i<3; ++i) { if (i != 2) { s += to16Str(v[i]) + SEMICOLON; } else { s += to16Str(v[i]) + MM; } }; cout << s; } bool isSame(vector<int> v, vector<int> last) { for (int i=0; i<v.size(); ++i) { if (v[i] != last[i]) { return false; } } return true; } bool isReset(vector<int> v) { for (int i=0; i<v.size(); ++i) { if (v[i] != 0) { return false; } } return true; } void printTO(vector<int> v, vector<int> last) { if (isSame(v, last)){ cout << BLANK; } else if(isReset(v)){ cout << RESET << BLANK; } else { cout << BEFORE; printRGB(v); cout << BLANK; } } int charToNum(char c) { if (c >= '0' && c <= '9') { return c - '0'; } else { return c - 'a' + 10; } } int strToNum(string s) { //求出16进制颜色的10进制表示 int num; num = charToNum(s[1]); num += charToNum(s[0])*16; return num; } void strToRGB(string s, vector<int> &v) { //将HTML格式的颜色转化为RGB形式 int num; s.erase(0, 1); if (s.size() == 1) { num = charToNum(s[0])*16; num += num/16; v.push_back(num); v.push_back(num); v.push_back(num); } else if (s.size() == 3) { num = charToNum(s[0])*16; num += num/16; v.push_back(num); //原来使用的s[0] + s[0] 运行错误 num = charToNum(s[1])*16; num += num/16; v.push_back(num); num = charToNum(s[2])*16; num += num/16; v.push_back(num); //cout << s1 << endl; } else { for (int i=0; i<3; ++i) { num = strToNum(s.substr(i*2, 2)); v.push_back(num); } } } void test() { int m, n, p, q; int ii=0, jj=0; //小色块的遍历基数 long long sum = 0; string s; vector<int> last; //记录前一个色块的颜色(背景色) last.resize(3, 0); //初始化为黑色 vector<vector<vector<int>>> v2; v2.reserve(1100); vector<vector<vector<int>>> v3; v3.reserve(1100); cin >> m >> n >> p >> q; for (int i=0; i<n; ++i) { vector<vector<int>> v1; v1.reserve(2000); for (int j=0; j<m; ++j) { cin >> s; vector<int> v; v.reserve(3); strToRGB(s, v); //将html格式的颜色转变为RGB格式 v1.push_back(v); } v2.push_back(v1); } //求各个小色块RGB和的平均值 while (ii < n) { vector<vector<int>> v1; v1.reserve(2000); while (jj < m) { vector<int> v; v.reserve(3); for (int t=0; t<3; ++t) { for (int i=ii; i<ii+q; ++i) { for (int j=jj; j<jj+p; ++j) { sum += v2[i][j][t]; } } v.push_back(sum/(p*q)); //整数除法自动向零取整 sum = 0; } v1.push_back(v); jj += p; } v3.push_back(v1); ii += q; jj = 0; } //打印输出 for (int i=0; i<n/q; ++i) { for (int j=0; j<m/p; ++j) { printTO(v3[i][j], last); last = v3[i][j]; } if (isReset(last)) { cout << ENTER; } else { last[0] = last[1] = last[2] = 0; //初始化没想到 cout << RESET << ENTER; } } } int main() { ios::sync_with_stdio(false); test(); return 0; }

如果感觉有帮助,记得点个赞,让我开心开心,哈哈

最新回复(0)