目录

  • 题目来源
  • 知识点
  • 注意点
  • 0分(略了)
  • 20分
  • 100分
  • 代码挺长的,可以修改/删除一些地方(比如规划输出那一段中一长串字符的定义,可以从题目中就知道,就不用再转来转去了),优化一些地方(最后两个大循环应该可以并到一起),删除一些注释掉了的段落,但是懒得弄了。
  • 参考文章

题目来源

字符画

知识点

  1. C++头文件 #include <stdlib.h> 中的 system(“color xx”); (改成ASCII的输出后后,用不上哦)
    system(“color XX”)函数可用于修改控制台背景及文字颜色。
    第一个X是背景颜色,第二个X是前颜色。(都是16进制的单个字符)
    在我写的代码中没有指明XX。就是默认的前白后黑了。

注意点

  1. ‘\xabcdef’ 输出时, '\x’需要进行转义。 即 ‘\\x’。
  2. 输入中的 #abcdef 中, abcdef是数字或小写字母。
  3. 在将输出转换为ASCII码时, 要记得将16进制数字符串填充成2位的。在我的代码中,特别要注意 RGB某一个为0的情况!

0分(略了)

20分

0分->20分: 之前以为输入的#abcdef中,abcdef会是数字或大写字母。在网上看了大佬的测试样例才意识到是小写字母。
通过了前 20 分的测试点。 (注意点2)
数据特点: m <= 10, n <= 10, p = 1, q = 2;

(有点呆的代码。不太了解c++, 无法熟练运用其中的各种便利的技巧。)

#include <iostream>
#include <fstream>
//#include <stdlib.h>  // sysytem()
#include <map>using namespace std;map<char, int> s2t;  // 16转10
map<int, char> t2s;  // 10转16// 16进制字符串转10进制数字
int sixteen2ten(string sixteen) {int num = 0;for (char c: sixteen) {num = num * 16 + s2t[c];}return num;
}// 10进制数字转“\x” + 16进制字符串
string ten2sixteen(int ten) {string sixteen = "";int shang = 0, yu = 0;string invSixteen = "";  // 倒序16进制字符串while (ten != 0) {yu = ten % 16;shang = ten / 16;ten = shang;invSixteen.push_back(t2s[yu]);}// 将逆序的调整为正序if (invSixteen.size() == 1) {sixteen = "0";}for (int i = invSixteen.size() - 1; i >= 0; --i) {sixteen.push_back(invSixteen[i]);}return "\\x" + sixteen;
}int main() {//ifstream cin("in3.txt");//system("color");  // 使终端能根据输出进行颜色变换, 现在这个格式的输出不行。// 初始化s2t['0'] = 0, s2t['1'] = 1, s2t['2'] = 2, s2t['3'] = 3, s2t['4'] = 4, s2t['5'] = 5, s2t['6'] = 6, s2t['7'] = 7, s2t['8'] = 8, s2t['9'] = 9, s2t['a'] = 10, s2t['b'] = 11, s2t['c'] = 12, s2t['d'] = 13, s2t['e'] = 14, s2t['f'] = 15;  // 注意是小写的//s2t['0'] = 0, s2t['1'] = 1, s2t['2'] = 2, s2t['3'] = 3, s2t['4'] = 4, s2t['5'] = 5, s2t['6'] = 6, s2t['7'] = 7, s2t['8'] = 8, s2t['9'] = 9, s2t['A'] = 10, s2t['B'] = 11, s2t['C'] = 12, s2t['D'] = 13, s2t['E'] = 14, s2t['F'] = 15;t2s[0] = '0', t2s[1] = '1', t2s[2] = '2', t2s[3] = '3', t2s[4] = '4', t2s[5] = '5', t2s[6] = '6', t2s[7] = '7', t2s[8] = '8', t2s[9] = '9', t2s[10] = 'A', t2s[11] = 'B', t2s[12] = 'C', t2s[13] = 'D', t2s[14] = 'E', t2s[15] = 'F';int m, n;  // 宽、高——列、行cin>>m>>n;int p, q;  // 每一小块的宽、高——列、行cin>>p>>q;// 存储输入 并 填充string inputStr[n][m];  // 存储输入 , 注意这里是 n行 m列 (有点乱哈)for (int i = 0; i < n; ++i) {  // 高for (int j = 0; j < m; ++j) {  // 宽string tmp, t;cin>>tmp;if (tmp.size() == 2) {  // #a  -> #aaaaaat = tmp;for (int ii = 0; ii < 5; ++ii) {t.push_back(tmp[1]);}}else if (tmp.size() == 4) {  // #abc  -> #aabbcct = "#";for (int ii = 1; ii <= 3; ++ii) {t.push_back(tmp[ii]);t.push_back(tmp[ii]);}}else {  // #abcdeft = tmp;}//cout<<"i: "<<i<<" j: "<<j<<" t: "<<t<<endl;inputStr[i][j] = t;}}//cout<<"OK"<<endl;int M = n / q, N = m / p;  // M行N列的色块int myRGB[M][N][3];   // 记录每一块的RGB平均值//cout<<M<<" "<<N<<endl;// 对每个色块中的像素取平均值for (int i = 0; i < M; ++i) {for (int j = 0; j < N; ++j) {// get每个色块的像素int sumR, sumG, sumB;sumR = sumG = sumB = 0;//cout<<i<<" "<<j<<endl;for (int ii = i * q; ii < i * q + q; ++ii) {for (int jj = j * p; jj < j * p + p; ++jj) {string cur = inputStr[ii][jj];string r = cur.substr(1, 2), g = cur.substr(3, 2), b = cur.substr(5, 2);sumR += sixteen2ten(r);sumG += sixteen2ten(g);sumB += sixteen2ten(b);//cout<<"i: "<<ii<<" j: "<<jj<<" "<<sixteen2ten(r)<<" "<<sixteen2ten(g)<<" "<<sixteen2ten(b)<<" * ";}}//cout<<endl<<endl;;myRGB[i][j][0] = sumR / (p * q);myRGB[i][j][1] = sumG / (p * q);myRGB[i][j][2] = sumB / (p * q);}}/*// 输出myRGBfor (int i = 0; i < M; ++i) {for (int j = 0; j < N; ++j) {cout<<myRGB[i][j][0]<<" "<<myRGB[i][j][1]<<" "<<myRGB[i][j][2]<<" * ";}cout<<endl;}*/// 规划输出 (或许可以和上边的合并哈)string ans = "";int preR = 0, preG = 0, preB = 0;string esc, kongge, kuohao, fenhao, zimum, shuzi48, shuzi0, shuzi2, huanhang;esc = ten2sixteen(27);kongge = ten2sixteen(' ');kuohao = ten2sixteen('[');fenhao = ten2sixteen(';');zimum = ten2sixteen('m');shuzi48 = ten2sixteen('4') + ten2sixteen('8');shuzi0 = ten2sixteen('0');shuzi2 = ten2sixteen('2');huanhang = ten2sixteen('\n');string changBackGround = esc + kuohao + shuzi48 + fenhao + shuzi2 + fenhao;  // ESC [ 3 8 ; 2 ;string resetBackGround = esc + kuohao + shuzi0 + zimum;  // ESC [ 0 mfor (int i = 0; i < M; ++i) {for (int j = 0; j < N; ++j) {// 先判断当前背景RGB是否与前一个相同// 相同, 不用改。 只需要添加一个色块if (myRGB[i][j][0] == preR && myRGB[i][j][1] == preG && myRGB[i][j][2] == preB) {ans += kongge;//cout<<"*"<<endl;}else {  // 不同, 需要改// 和默认的一致(0,0,0), 使用重置if (myRGB[i][j][0] == 0 && myRGB[i][j][1] == 0 && myRGB[i][j][2] == 0) {ans += resetBackGround;ans += kongge;}else {// ESC [ ; 4 8 ;ans += changBackGround;int shang, yu;// R ;string curR;shang = myRGB[i][j][0], yu = 0;while (shang != 0) {  // 这样是倒序的yu = shang % 10;shang = shang / 10;curR = ten2sixteen(yu + '0') + curR;  // 这样一下就正序了}ans += curR;//ans += ten2sixteen(myRGB[i][j][0]);ans += fenhao;// G ;string curG;shang = myRGB[i][j][1], yu = 0;while (shang != 0) {yu = shang % 10;shang = shang / 10;curG = ten2sixteen(yu + '0') + curG;}ans += curG;ans += fenhao;// Bstring curB;shang = myRGB[i][j][2], yu = 0;while (shang != 0) {yu = shang % 10;shang = shang / 10;curB = ten2sixteen(yu + '0') + curB;}ans += curB;//ans += fenhao; /* 不需要!!! B后边不需要分号!!!*/// 添加 mans += zimum;// 添加色块ans += kongge;}//preR = myRGB[i][j][0];preG = myRGB[i][j][1];preB = myRGB[i][j][2];}}// 该行结束// 1. 还原成默认背景色, 使用重置 2. 修改preRGB 3. 添加换行符if (preR != 0 || preG != 0 || preB != 0) {ans += resetBackGround;preR = preG = preB = 0;}ans += huanhang;}cout<<ans;return 0;
}

100分

20->100: 在十进制转16进制函数中,自己写代码的时候没有考虑当数字为0要输出\x00。改了这个函数以及主函数中最后一个循环中的RGB部分就好了。(注意点3)

#include <iostream>
#include <fstream>
#include <stdlib.h>  // sysytem()
#include <map>using namespace std;map<char, int> s2t;  // 16转10
map<int, char> t2s;  // 10转16// 16进制字符串转10进制数字
int sixteen2ten(string sixteen) {int num = 0;for (char c: sixteen) {num = num * 16 + s2t[c];}return num;
}// 10进制数字转16进制字符串
string ten2sixteen(int ten) {string sixteen = "";int shang = 0, yu = 0;string invSixteen = "";  // 倒序16进制字符串while (ten != 0) {yu = ten % 16;shang = ten / 16;ten = shang;invSixteen.push_back(t2s[yu]);}// 将逆序的调整为正序if (invSixteen.size() == 1) {sixteen = "0";}if (invSixteen.size() == 0) {  /* 这个不要忘啦 */sixteen = "00";//cout<<"HELLO"<<endl;}for (int i = invSixteen.size() - 1; i >= 0; --i) {sixteen.push_back(invSixteen[i]);}return "\\x" + sixteen;
}int main() {//ifstream cin("in3.txt");//system("color");  // 使终端能根据输出进行颜色变换// 初始化s2t['0'] = 0, s2t['1'] = 1, s2t['2'] = 2, s2t['3'] = 3, s2t['4'] = 4, s2t['5'] = 5, s2t['6'] = 6, s2t['7'] = 7, s2t['8'] = 8, s2t['9'] = 9, s2t['a'] = 10, s2t['b'] = 11, s2t['c'] = 12, s2t['d'] = 13, s2t['e'] = 14, s2t['f'] = 15;t2s[0] = '0', t2s[1] = '1', t2s[2] = '2', t2s[3] = '3', t2s[4] = '4', t2s[5] = '5', t2s[6] = '6', t2s[7] = '7', t2s[8] = '8', t2s[9] = '9', t2s[10] = 'A', t2s[11] = 'B', t2s[12] = 'C', t2s[13] = 'D', t2s[14] = 'E', t2s[15] = 'F';int m, n;  // 宽、高——列、行cin>>m>>n;int p, q;  // 每一小块的宽、高——列、行cin>>p>>q;// 存储输入 并 填充string inputStr[n][m];  // 存储输入 , 注意这里是 n行 m列 (有点乱哈)for (int i = 0; i < n; ++i) {  // 高for (int j = 0; j < m; ++j) {  // 宽string tmp, t;cin>>tmp;if (tmp.size() == 2) {  // #a  -> #aaaaaat = tmp;for (int ii = 0; ii < 5; ++ii) {t.push_back(tmp[1]);}}else if (tmp.size() == 4) {  // #abc  -> #aabbcct = "#";for (int ii = 1; ii <= 3; ++ii) {t.push_back(tmp[ii]);t.push_back(tmp[ii]);}}else {  // #abcdeft = tmp;}//cout<<"i: "<<i<<" j: "<<j<<" t: "<<t<<endl;inputStr[i][j] = t;}}//cout<<"OK"<<endl;int M = n / q, N = m / p;  // M行N列的色块int myRGB[M][N][3];   // 记录每一块的RGB平均值//cout<<M<<" "<<N<<endl;// 对每个色块中的像素取平均值for (int i = 0; i < M; ++i) {for (int j = 0; j < N; ++j) {// get每个色块的像素int sumR, sumG, sumB;sumR = sumG = sumB = 0;//cout<<i<<" "<<j<<endl;for (int ii = i * q; ii < i * q + q; ++ii) {for (int jj = j * p; jj < j * p + p; ++jj) {string cur = inputStr[ii][jj];string r = cur.substr(1, 2), g = cur.substr(3, 2), b = cur.substr(5, 2);sumR += sixteen2ten(r);sumG += sixteen2ten(g);sumB += sixteen2ten(b);//cout<<"i: "<<ii<<" j: "<<jj<<" "<<sixteen2ten(r)<<" "<<sixteen2ten(g)<<" "<<sixteen2ten(b)<<" * ";}}//cout<<endl<<endl;;myRGB[i][j][0] = sumR / (p * q);myRGB[i][j][1] = sumG / (p * q);myRGB[i][j][2] = sumB / (p * q);}}/*// 输出myRGBfor (int i = 0; i < M; ++i) {for (int j = 0; j < N; ++j) {cout<<myRGB[i][j][0]<<" "<<myRGB[i][j][1]<<" "<<myRGB[i][j][2]<<" * ";}cout<<endl;}*/// 规划输出string ans = "";int preR = 0, preG = 0, preB = 0;string esc, kongge, kuohao, fenhao, zimum, shuzi48, shuzi0, shuzi2, huanhang;esc = ten2sixteen(27);kongge = ten2sixteen(' ');kuohao = ten2sixteen('[');fenhao = ten2sixteen(';');zimum = ten2sixteen('m');shuzi48 = ten2sixteen('4') + ten2sixteen('8');shuzi0 = ten2sixteen('0');shuzi2 = ten2sixteen('2');huanhang = ten2sixteen('\n');string changBackGround = esc + kuohao + shuzi48 + fenhao + shuzi2 + fenhao;  // ESC [ 3 8 ; 2 ;string resetBackGround = esc + kuohao + shuzi0 + zimum;  // ESC [ 0 mfor (int i = 0; i < M; ++i) {for (int j = 0; j < N; ++j) {// 先判断当前背景RGB是否与前一个相同// 相同, 不用改。 只需要添加一个色块if (myRGB[i][j][0] == preR && myRGB[i][j][1] == preG && myRGB[i][j][2] == preB) {ans += kongge;//cout<<"*"<<endl;}else {  // 不同, 需要改// 和默认的一致(0,0,0), 使用重置if (myRGB[i][j][0] == 0 && myRGB[i][j][1] == 0 && myRGB[i][j][2] == 0) {ans += resetBackGround;ans += kongge;}else {// ESC [ ; 4 8 ;ans += changBackGround;int shang, yu;// R ;string curR;shang = myRGB[i][j][0], yu = 0;if (shang == 0) {curR = ten2sixteen('0');}else {while (shang != 0) {  // 这样是倒序的yu = shang % 10;shang = shang / 10;curR = ten2sixteen(yu + '0') + curR;  // 这样一下就正序了}}ans += curR;//ans += ten2sixteen(myRGB[i][j][0]);ans += fenhao;// G ;string curG;shang = myRGB[i][j][1], yu = 0;if (shang == 0) {curG = ten2sixteen('0');}else {while (shang != 0) {yu = shang % 10;shang = shang / 10;curG = ten2sixteen(yu + '0') + curG;}}ans += curG;ans += fenhao;// Bstring curB;shang = myRGB[i][j][2], yu = 0;if (shang == 0) {curB = ten2sixteen('0');}else {while (shang != 0) {yu = shang % 10;shang = shang / 10;curB = ten2sixteen(yu + '0') + curB;}}ans += curB;//ans += fenhao; /* 不需要!!! B后边不需要分号!!!*/// 添加 mans += zimum;// 添加色块ans += kongge;}//preR = myRGB[i][j][0];preG = myRGB[i][j][1];preB = myRGB[i][j][2];}}// 该行结束// 1. 还原成默认背景色, 使用重置 2. 修改preRGB 3. 添加换行符if (preR != 0 || preG != 0 || preB != 0) {ans += resetBackGround;preR = preG = preB = 0;}ans += huanhang;}cout<<ans;return 0;
}

代码挺长的,可以修改/删除一些地方(比如规划输出那一段中一长串字符的定义,可以从题目中就知道,就不用再转来转去了),优化一些地方(最后两个大循环应该可以并到一起),删除一些注释掉了的段落,但是懒得弄了。

参考文章

从0分到100分,全靠这篇文章中给出的测试数据。(自己懒了点,也没想到那两个方面)
CCF CSP 20190903 字符画 100分

CSP CCF: 201909-3 字符画) (C++)相关推荐

  1. CCF系列题解--2015年12月第三题 ASCII字符画

    问题描述 用 ASCII 字符来画图是一件有趣的事情,并形成了一门被称为 ASCII Art 的艺术.例如,下图是用 ASCII 字符画出来的 CSPRO 字样. ..____.____..____. ...

  2. csp字符画c语言,CCF-CSP:201909-3字符画

    题目 编号: 201909-3 试题名称: 字符画 时间限制: 5.0s 内存限制: 512.0MB 题目背景 君君是个喜欢旅行的女孩子,世界那么大,她哪里都想去看看.这个暑假,她踏遍了大江南北,感慨 ...

  3. 基于Python实现图画转换字符画

    微信改版,加星标不迷路! 基于Python实现图画转换字符画 作者:阿广 概述 前言 准备工作 识别原理 静态图像处理 动态图像处理 结果 阿广说 群聊交流 福利一刻 推荐阅读 前言 前几天写了基于P ...

  4. Python趣味编程小技巧,图片转炫酷字符画,一看就是高手

    hello大家好,今天我又发现了个有趣的小玩意.我是专写有趣小玩意的老师. 老规矩,先上效果图 今天做这个图片转字符画是用到了pil库.这是一个专门用来处理图片的python库.自己直接用pip安装下 ...

  5. Linux控制台打开显示字符画,Linux 命令行字符画工具

    代码地址:https://github.com/pedroqin/Ascii_Signature 公众号: write_simple_demo,专注linux 介绍 此项目移植于网页版字符画生成器,最 ...

  6. python图片转字符画

    学习了下python图片转字符画,学习连接:Python 图片转字符画,觉得还挺有趣,不过图片的颜色和细节不能太多,不然效果比较差,代码如下: from PIL import Image import ...

  7. python项目实战:最简单的图片转字符画

    2019独角兽企业重金招聘Python工程师标准>>> 前言 今天为大家一个基础的,且简单的Python图片转字符画的过程,python图像转字符画需要用到matplotlib.py ...

  8. python动态图片转字符画_GIF动态图,视频?都能用Python转换成字符画图像

    字符画是一种由字母.标点或其他字符组成的图画,它产生于互联网时代,在聊天软件中使用较多,本文我们看一下如何将自己喜欢的图片转成字符画. 静态图片 首先,我们来演示将静态图片转为字符画,功能实现主要用到 ...

  9. Python实现将图片转字符画

    from PIL import Image # PIL 是一个 Python 图像处理库ascii_char = list("$@B%8&WM#*oahkbdpqwmZO0QLCJU ...

最新文章

  1. unique函数_C++智能指针2:(虚?)析构函数(标准与实现的差异)
  2. HTML5 视频转换软件 Freemake Video Converter
  3. 拷贝构造函数的第一个参数必须是自身类类型的引用
  4. 【洛谷P3106】[USACO14OPEN]GPS的决斗Dueling GPS's
  5. QT 托盘图标退出延迟解决方案
  6. 利用 Spring MVC 上传多文件到指定目录 spring upload files
  7. Qt学习笔记之项目管理(pro)文件
  8. pdf数据填充,JaspersoftStudio,JasperReport
  9. Vue基础知识之vue-resource和axios(三)
  10. [Java集合源码阅读]-ArrayList扩容机制
  11. oracle去除逗号函数,oracle逗号分隔函数
  12. 哈理工OJ 1184 早起一水(水题)
  13. 使用wxPython内嵌浏览器
  14. 有哪些让你印象深刻的bug?
  15. 惊爆:Alexa 全球排名网站即将关闭
  16. 终端安全管理之殇:安全管控能力与用户体验
  17. 零死角玩转stm32初级篇5-流水灯的前后今生
  18. 定积分在几何学上的应用
  19. 双周报 1月 vol.1 | VMware 上线 DevOps 平台;白宫召开开源安全峰会
  20. Google Authenticator windows client 谷歌身份验证器 windows 电脑端

热门文章

  1. thinkpad重装系统不引导_联想Y400电脑装WIN7无法重装系统的解决方法
  2. 全网最细海龟 (turtle) 画图讲解 (五):输入/输出文字及鼠标与键盘交互设计
  3. 研发质量管理的“红与黑”
  4. ASP.Net免费发送短信
  5. sbuf.st_size 为负数
  6. cocos 使用ts对接微信广告
  7. 操作系统——精髓与设计原理(第九版)
  8. 小米手机页面显示android,小米手机连接电脑不显示文件怎么办?
  9. 诛仙3 私服架设 仿官网
  10. db2 hadr 起停顺序_电机顺序启停问题