题目
用时
这个看题就头大了,所以也没计时,边写博客边看的
花了小20分钟看题目描述
然后才发现里面基本都是没用的
换句话说
题目描述对不对?对。
它对解题有没有帮助?没有。
出题人脑子有泡
幸亏九月份没考
不然我心态就炸了
还有
考试的机子是Win的我拿头去写Linux命令?
真是服了
思路分析
-
24位图:每个像素由24b即3B来表示,如
#ABCDEF
该像素的RGB分量分别为0xAB
0xCD
0xEF
-
然后看输入格式
2 2 (原图片宽2像素,高2像素)
1 2 (分成宽1像素,高2像素的块)
#111111
#0
#000000
#111
(原图的四个像素,从左到右,从上到下,注意缩写的问题) -
输出格式
ASCII码对照表
十六进制值 | 解释 |
---|---|
1B | ESC |
5B | [ |
34 | 4 |
38 | 8 |
3B | ; |
32 | 2 |
6D | m |
20 | 空格 |
30 | 0 |
0A | 换行 |
ESC用\033表示,翻译成Linux终端能识别的命令就是
\033[48;2;8;8;8m \033[0m\n
即将字符背景色设为RGB =(8, 8, 8)的色号,字符颜色默认,输出字符为两个空格
执行一下试试
换一个背景色为(255, 255, 255)看看
这些就是那个脑残问题描述里说的内容,做题时只需要输出那堆ASCII码序列就行了
还有很重要的一点:因为输出的字符是空格所以前景色是不需要设置的,也就是说输出序列中绝对不会出现对前景色的更改语句!只改背景色就可以了
出题人就是个傻叉,故意混淆视听
- 样例解释
分成两个块后,每个块都包含上下两个像素,块的RGB值取两个像素的均值(向下取整)
比如第一像素#111111
和第三像素#000000
属于同一块
十进制的RGB分别为(17, 17, 17)和(0, 0, 0)
取均值后块的RGB值为十进制的(8, 8, 8)
第二像素#0
和第四像素#111
属于同一块
取均值后块的RGB值也为十进制的(8, 8, 8)
输出时按行和块输出,每个空格代表一个块,每输出完一行输出一个换行符
总块数为(2*2)/(1*2)=2
行数为2/2=1
代码
80分,主要是运行超时了
输出都没问题
应该是那个三重循环时间复杂度太高了
正在想办法重构
我太难了…
class Pixel:
# 像素类
R = 0
G = 0
B = 0
# 十进制RGB值
def set_RGB(self, R, G, B):
self.R = R
self.G = G
self.B = B
def str_to_ASCII(mystr):
# 将字符串逐个字符转为\xAB的形式
final_ASCII_str = ''
for mychr in mystr:
final_ASCII_str += hex(ord(mychr)).replace('0x', '\\x')
return final_ASCII_str
def background_color(R, G, B):
# 传入十进制的RGB值生成更改背景色的ASCII序列
background_color_sequence = '\\x1b' + str_to_ASCII('[48;2')
background_color_sequence += str_to_ASCII(';' + str(R) + ';' + str(G) + ';' + str(B) + 'm')
return background_color_sequence
if __name__ == "__main__":
img_width, img_height = map(int, input().split(' '))
# 获得图片的宽度、高度
block_width, block_height = map(int, input().split(' '))
# 获得块的宽度、高度
rows_num = int(img_height / block_height)
# 行数
row_blocks_num = int(img_width / block_width)
# 每行块数
img_pix = []
# 图片像素存储,如两行四列图片的格式为
'''
[
[pixel, pixel, pixel, pixel],
[pixel, pixel, pixel, pixel]
]
'''
block_pix_group = [[[] for rbn in range(row_blocks_num)]for rn in range(rows_num)]
# 一个块包含数个pixel对象
block_pix = []
# 取均值后每块只按一个pixel对象存储
lower_sequence = ''
reset_sequence = '\\x1b' + str_to_ASCII('[0m')
# 重置序列 \x1b\x5b\x30\x6d\x0a 即 ESC[0m
terminal_color = [0, 0, 0]
# 初始终端颜色
for ih in range(img_height):
img_pix.append([])
for iw in range(img_width):
# 读入每个像素并存储为十进制RGB分量
img_pix[ih].append(Pixel())
orig_HEX_RGB = input().replace('#', '')
# 拿到一个十六进制RGB值如ABCDEF
if len(orig_HEX_RGB) == 1:
# 缩写为1的情况
orig_HEX_RGB += orig_HEX_RGB * 5
elif len(orig_HEX_RGB) == 3:
# 缩写为3的情况
orig_HEX_RGB = orig_HEX_RGB[0] * 2 + orig_HEX_RGB[1] * 2 + orig_HEX_RGB[2] * 2
img_DEC_R = int(orig_HEX_RGB[0:2], 16)
img_DEC_G = int(orig_HEX_RGB[2:4], 16)
img_DEC_B = int(orig_HEX_RGB[4:6], 16)
# 获得图片每个像素的十进制RGB值
img_pix[ih][iw].set_RGB(img_DEC_R, img_DEC_G, img_DEC_B)
# 存储到pixel对象中
block_pix_group[ih // block_height][iw // block_width].append(img_pix[ih][iw])
# 确定每个块包含图片中的哪几个pixel对象
for rn in range(rows_num):
block_pix.append([])
for rbn in range(row_blocks_num):
block_pix[rn].append(Pixel())
block_sum_R = 0
block_sum_G = 0
block_sum_B = 0
# TODO:分离下面的三重循环
for po in block_pix_group[rn][rbn]:
# 分别求每个块包含所有pixel对象的R、G、B的和
block_sum_R += po.R
block_sum_G += po.G
block_sum_B += po.B
block_average_R = block_sum_R // (block_width * block_height)
block_average_G = block_sum_G // (block_width * block_height)
block_average_B = block_sum_B // (block_width * block_height)
# 向下取整求每块的RGB均值
block_pix[rn][rbn].set_RGB(block_average_R, block_average_G, block_average_B)
# 存放到一个pixel对象中
this_block_pix_R = block_pix[rn][rbn].R
this_block_pix_G = block_pix[rn][rbn].G
this_block_pix_B = block_pix[rn][rbn].B
# 一个块的RGB值
if [this_block_pix_R, this_block_pix_G, this_block_pix_B] != terminal_color:
# 如果块与终端颜色不同
if this_block_pix_R == 0 and this_block_pix_G == 0 and this_block_pix_B == 0:
# 如果与默认色相同
lower_sequence += reset_sequence
# 则加一个重置序列
else:
lower_sequence += background_color(this_block_pix_R, this_block_pix_G, this_block_pix_B)
# 与默认色不同则加一个更改背景色的序列
terminal_color = [this_block_pix_R, this_block_pix_G, this_block_pix_B]
# 更新终端背景色
lower_sequence += str_to_ASCII(' ')
# 无论块RGB与终端是否相同都要输出一个空格
if terminal_color != [0, 0, 0]:
# 输出一行后如果终端颜色不是默认的000则加一个重置序列
lower_sequence += reset_sequence
terminal_color = [0, 0, 0]
# 重置终端背景色
lower_sequence += '\\x0a'
# 每输出一行必加一个换行
# 所有块全部处理完一遍
upper_sequence = ''
for i in range(len(lower_sequence)):
if lower_sequence[i] in {'a', 'b', 'c', 'd', 'e', 'f'}:
# 如果是小写字母abcdef
upper_sequence += lower_sequence[i].upper()
# 转为大写
else:
upper_sequence += lower_sequence[i]
print(upper_sequence)
测试用例
引用自此博客,C满分代码
一定要注意最终输出的格式!
第一:是ASCII码格式的 \x..
第二:输出的ABCDEF都是大写的,如果输出小写则0分
第三:输出只有一行,不要加换行
1 1
1 1
#010203
\x1B\x5B\x34\x38\x3B\x32\x3B\x31\x3B\x32\x3B\x33\x6D\x20\x1B\x5B\x30\x6D\x0A
2 2
1 2
#111111
#0
#000000
#111
\x1B\x5B\x34\x38\x3B\x32\x3B\x38\x3B\x38\x3B\x38\x6D\x20\x20\x1B\x5B\x30\x6D\x0A
1 1
1 1
#0
\x20\x0A
2 2
2 1
#111111
#0
#000000
#111
\x1B\x5B\x34\x38\x3B\x32\x3B\x38\x3B\x38\x3B\x38\x6D\x20\x1B\x5B\x30\x6D\x0A\x1B\x5B\x34\x38\x3B\x32\x3B\x38\x3B\x38\x3B\x38\x6D\x20\x1B\x5B\x30\x6D\x0A
2 2
2 1
#111111
#0
#000000
#000
\x1B\x5B\x34\x38\x3B\x32\x3B\x38\x3B\x38\x3B\x38\x6D\x20\x1B\x5B\x30\x6D\x0A\x20\x0A
3 2
1 2
#0
#0
#010101
#010102
#0
#0
\x1B\x5B\x34\x38\x3B\x32\x3B\x30\x3B\x30\x3B\x31\x6D\x20\x1B\x5B\x30\x6D\x20\x20\x0A
1 2
1 2
#123456
#abcdef
\x1B\x5B\x34\x38\x3B\x32\x3B\x39\x34\x3B\x31\x32\x38\x3B\x31\x36\x32\x6D\x20\x1B\x5B\x30\x6D\x0A
2 1
2 1
#654321
#fedcba
\x1B\x5B\x34\x38\x3B\x32\x3B\x31\x37\x37\x3B\x31\x34\x33\x3B\x31\x30\x39\x6D\x20\x1B\x5B\x30\x6D\x0A
总结
说难也没有很难吧
可能是我数据结构选的不好
导致必须用三重循环才能拿到需要的数据
翻遍全网也没找到一份Python的满分代码
只看到一个和我一样运行超时的80分
有点难受
不过还是感谢Python提供了许多内置函数如replace
ord
hex
int
等等等等
我永远喜欢Python