1 条题解

  • 0
    @ 2025-5-19 16:55:16

    题目描述

    洛基有一个使用四个7段显示器来显示时间的LED闹钟。每个7段显示器由七个条形段组成,通过点亮不同的段来显示不同的数字。每个段可以表示为一个比特位,因此一个数字可以表示为一个7位的二进制数。例如,数字“3”对应的二进制表示为1111001(比特顺序为1到7)。

    某些段可能“烧坏”了,即即使应该点亮,也不会显示。例如,如果数字“3”的比特7对应的段烧坏了,那么实际显示会缺少底部的横线。题目给出两个时间点的LED显示状态(每个时间点由四个7位二进制字符串表示,共八个字符串),要求根据这两个显示状态推断出第二个时间点的实际时间。已知烧坏的段在两个时间点之间是一致的,且每个数据集只有一个可能的解。

    解题思路

    1. 理解7段显示器和烧坏段的影响:每个数字由7个段的点亮状态决定。如果某个段烧坏了,那么无论显示哪个数字,该段都不会亮。因此,烧坏的段是所有数字显示中共同缺失的段。

    2. 确定烧坏的段:我们需要找出在两个时间点的所有显示数字中,哪些段在所有情况下都未被点亮。这些段就是烧坏的段。具体来说,对于每个段(比特位),如果在所有八个显示字符串中该位都是0,那么这个段就是烧坏的。

    3. 恢复原始数字:一旦确定了烧坏的段,就可以通过将观察到的显示与烧坏的段进行“或”操作来恢复原始的数字显示。例如,如果段7烧坏了,那么任何数字的段7都不会亮,但实际上数字可能应该点亮段7。因此,我们需要将烧坏的段对应的比特位“补上”,即假设这些段原本是点亮的。

    4. 验证时间合法性:恢复原始数字后,需要检查这些数字是否构成合法的时间。合法时间的小时部分在1到12之间,分钟部分在0到59之间。

    5. 确定唯一解:由于题目保证每个数据集只有一个可能的解,因此一旦恢复的数字满足时间合法性,就可以直接输出。

    解决步骤

    1. 读取输入:对于每个测试用例,读取八个7位二进制字符串,前四个表示第一次时间,后四个表示第二次时间。

    2. 确定烧坏的段:对于每个比特位(1到7),检查在所有八个字符串中该位是否都是0。如果是,则该段烧坏。

    3. 恢复第二次时间的原始显示

      • 对于第二次时间的每个数字(四个字符串),将烧坏的段对应的比特位设置为1(因为烧坏的段不亮,但实际可能应该亮)。
      • 这样得到的二进制字符串表示的是理想情况下(无烧坏)的数字显示。
    4. 将二进制字符串转换为数字

      • 预先建立一个字典,将每个数字(0到9)映射到其标准的7位二进制表示。
      • 对于恢复后的每个二进制字符串,查找匹配的数字。
    5. 验证并输出时间

      • 将四个数字组合成时间格式HH:MM,并检查小时和分钟的合法性。
      • 输出合法的时间字符串,不包含前导零。

    示例代码

    # 预定义数字到二进制字符串的映射(比特顺序为1到7)
    digit_to_bits = {
        0: '1111110',
        1: '0110000',
        2: '1101101',
        3: '1111001',
        4: '0110011',
        5: '1011011',
        6: '1011111',
        7: '1110000',
        8: '1111111',
        9: '1111011'
    }
    
    # 反向映射:二进制字符串到数字
    bits_to_digit = {v: k for k, v in digit_to_bits.items()}
    
    def solve():
        n = int(input())
        for _ in range(n):
            displays = input().split()
            first_four = displays[:4]
            last_four = displays[4:]
            
            # 确定烧坏的段:在所有八个显示中,某一位始终是0
            burned = [True] * 7  # 初始假设所有段都烧坏了
            for i in range(7):
                for display in displays:
                    if display[i] == '1':
                        burned[i] = False
                        break
            
            # 恢复第二次显示的原始比特
            recovered = []
            for display in last_four:
                original = list(display)
                for i in range(7):
                    if burned[i]:
                        original[i] = '1'  # 烧坏的段实际可能是点亮的
                recovered.append(''.join(original))
            
            # 将恢复的比特映射到数字
            time_digits = []
            for bits in recovered:
                time_digits.append(bits_to_digit.get(bits, -1))
            
            # 组合时间
            h1, h2, m1, m2 = time_digits
            hour = h1 * 10 + h2
            minute = m1 * 10 + m2
            
            # 确保小时和分钟合法
            if 1 <= hour <= 12 and 0 <= minute <= 59:
                # 格式化输出,不包含前导零
                print(f"{hour}:{minute:02d}")
    
    solve()
    

    注意事项

    1. 烧坏段的确定:只有在所有八个显示中某一位都是0时,才能确定该段烧坏。如果有任何一个显示中该位是1,则该段未烧坏。
    2. 时间合法性:恢复的数字必须组合成合法的时间(小时1-12,分钟0-59)。
    3. 唯一解:题目保证唯一解,因此无需处理多解情况。
    4. 输出格式:小时不包含前导零,分钟必须是两位数(如9:05而不是9:5)。

    通过以上步骤,可以准确推断出第二个时间点的实际时间。

    • 1

    信息

    ID
    1021
    时间
    1000ms
    内存
    30MiB
    难度
    (无)
    标签
    递交数
    0
    已通过
    0
    上传者