CCF-201909-3-字符画

这题大家有冷静看过的话,发现其实并不难。。考试和练习真的心态不一样啊。。。

题目大意
把图片中的像素平均分成n份,每一份叫一块,这个块的像素值就是这些像素的平均值,然后再在控制台输入改颜色的命令和空格。还要把命令的每个字符转成ASCII码,16进制的。

步骤
懂了题意后,步骤就清晰了

  1. 处理输入,因为输入的颜色是从左到右从上到下的顺序,一般的想法是每读取m个换行就存入数组,这样就得花多m* n(最大1920*1080)的数组了。
    所以这里我直接就利用读取的像素颜色的下标推出像素是位于几行几列,然后推出位于哪个块,就直接把颜色加进那个块,后面再同一取平均。这样就只用p * q空间的数组就可以了。这个数组就是压缩后的图像。
    颜色格式的处理也好办。下面再具体介绍。

  2. 取平均,每个像素块除与 p*q

  3. 从左到右,从上到下遍历压缩后的图像,一个个像素涂色。
    根据规则:

    • 颜色和前面不一样(颜色有改变),就要输入命令改变颜色(背景色)。
      + 颜色要变成默认色的,就直接用重置命令,就是 ESC[0;m 那个。
      + 变成其他颜色的用终端背景色的命令,就是 ESC[48;2 那个。
    • 颜色一样就不用输入命令啦
    • 处理完命令记得输入字符啊,输入空格
  4. 输入完一行后,还要判断终端背景色是不是恢复默认色,否则输入重置,重置回默认色。

  5. 每行结束后,还要一个空格。

细节
1.颜色的处理:
统一转成6位的:比如 #a --> #aaaaaa, #abc --> #aabbcc。这好办吧,不多说了。
再分三段分出R,G,B, 比如 #aabbcc --> R:aa G:bb B:cc
然后再把16进制的颜色转为10进制。用 int( hex_str , 16 )转,最后把对应颜色加进对应的块的RGB中

2.字符转ASCII,用 ord() 函数把字符转成10进制的ASCII码,再用hex()转成16进制字符串。这里转出来的格式是这样的 :0x2a, 题目中的格式是:\x2A。所以前面要换成斜杠“ \ ”, \x后面的字母要大写。

3.python的换行符“\n”转成16进制是 /xA,样例输出的换行符是 /x0A, 所以没办法,我们直接就用 “/x0A”代替换行符。

python代码
这里80分,后面两个样例太大了超时。理论上用其他语言,在练习题限制的5秒钟内能过的。python在考试时候的时间限制下应该能过,我记得是几十秒来着。

# 题目大意:把图片压缩模糊后,再在控制台输出命令
# 题目使用空格作为字符作字符画,因为空格是透明的
# 所以其实只要改变终端背景色就ok了,就是48;2那个
# 所以38;2的那个没用的。。。


def str2hax(s: str) -> str:
    """字符转特定的16进制"""
    res = ''
    for c in s:
        res += '\\x' + hex(ord(c))[2:].upper()
    return res


def wash_colorstr(s: str) -> tuple:
    """处理输入的颜色字符串"""
    if len(s) == 1:
        s = s * 6
    elif len(s) == 3:
        s = s[0] * 2 + s[1] * 2 + s[2] * 2
    r, g, b = int(s[:2], 16), int(s[2:4], 16), int(s[4:], 16)
    return r, g, b


def get_mean(arr: list):
    """取平均(除法向下取整)"""
    for line in arr:
        for pixel in line:
            pixel[0] //= p * q
            pixel[1] //= p * q
            pixel[2] //= p * q


def get_command_str(pixel: list) -> str:
    """返回控制台转义序列字符串"""
    # 如果是默认色,就直接重置
    if sum(pixel) == 0:
        return '\\x1B' + str2hax('[0m')
    return '\\x1B' + str2hax('[48;2;{};{};{}m'.format(pixel[0], pixel[1],
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值