我应该如何在患有红绿色盲的情况下通过 CF2214H Double Vision?
cancan123456 · · 休闲·娱乐
观察题目描述可知,本题主要考察选手是不是色盲。由生物学常识可知,最常见的色盲是红绿色盲,因此不难想到题目考察选手对红色与绿色的区分能力。
因此下载题目中唯一一张图片,并在目录下运行如下 Python 代码:
from PIL import Image
import numpy as np
# 读取图像
img = Image.open('filename.png') # 请将 filename.png 改为你的文件名
# 转换为RGB模式(确保图像是RGB格式)
if img.mode != 'RGB':
img = img.convert('RGB')
# 将图像转换为numpy数组
img_array = np.array(img)
# 提取RGB三个通道
r_channel = img_array[:, :, 0] # R通道
g_channel = img_array[:, :, 1] # G通道
b_channel = img_array[:, :, 2] # B通道
# 保存为图像文件
Image.fromarray(r_channel).save('R_channel.png')
Image.fromarray(g_channel).save('G_channel.png')
Image.fromarray(b_channel).save('B_channel.png')
# 可选:保存为文本文件(显示数值)
# np.savetxt('R_channel.txt', r_channel, fmt='%d')
# np.savetxt('G_channel.txt', g_channel, fmt='%d')
# np.savetxt('B_channel.txt', b_channel, fmt='%d')
print("RGB通道已提取并保存为:")
print("- R_channel.png")
print("- G_channel.png")
print("- B_channel.png")
可得如下三张图像(分别为 R、G、B 通道)。
不难观察到重复出现 13 次的 74 字样,因此输出 74 74 74 74 74 74 74 74 74 74 74 74 74 即可。
#include <cstdio>
using namespace std;
int main() {
printf("74 74 74 74 74 74 74 74 74 74 74 74 74");
return 0;
}
欸?我为什么没有通过此题?
再次观察题面,注意到题目名 Double Vision,不难联想到一种需要将两眼视觉错位叠加的图片:Autostereogram。
为了看出在 Autostereogram 中隐藏的信息,我们需要将两眼的焦平面移动至屏幕的前方或后方,达到将图像错位叠加的效果。
因此,我们需要将图像平移一段距离,求出与原图片的差,存储于新图片中。考虑到 Autostereogram 的平移量一般为一个重复单元的长度,我们需要求出其长度。
上图为原图的 R 通道,放大
from PIL import Image
import numpy as np
def shift_and_difference(image_path, shift_amount=100):
# 读取图像
img = Image.open(image_path)
# 转换为RGB模式(确保有三通道)
if img.mode != 'RGB':
img = img.convert('RGB')
# 获取图像尺寸
width, height = img.size
# 转换为numpy数组
img_array = np.array(img)
# 创建平移后的图像数组(用黑色填充移出的部分)
shifted_array = np.zeros_like(img_array)
# 向左平移:原图像的右侧部分移动到左侧
if shift_amount < width:
shifted_array[:, :width - shift_amount] = img_array[:, shift_amount:]
# 计算差值(绝对值差)
diff_array = np.abs(img_array.astype(np.int16) - shifted_array.astype(np.int16))
diff_array = diff_array.astype(np.uint8) # 转换回uint8类型
# 转换为PIL图像
diff_img = Image.fromarray(diff_array)
# 保存结果
diff_img.save('difference.png')
# 可选:保存平移后的图像用于调试
shifted_img = Image.fromarray(shifted_array)
shifted_img.save('shifted_left_' + str(shift_amount) + '.png')
return diff_img, shifted_img
# 执行平移和差分
shift = 171 # 定义平移量
difference_image, shifted_image = shift_and_difference('filename.png', shift_amount=shift) # 请将 filename.png 改为你的文件名
print("已完成操作:")
print("- 原始图像向左平移" + str(shift) + "像素")
print("- 计算原始图像与平移图像的差值")
print("- 结果保存为 difference.png")
print("- 平移图像保存为 shifted_left_" + str(shift) + ".png(用于调试)")
得到如下图片(difference.png):
不难读出文字内容:YU5zV2VS,输出该字符串即可。
参考代码:
#include <cstdio>
using namespace std;
int main() {
printf("YU5zV2VS");
return 0;
}