题解 | 小心火烛的歪

小心火烛的歪

https://www.nowcoder.com/practice/6cdb80dbb66c42eea179068a4afb25db

import sys
import itertools

def main():
    # 读取所有输入数据
    data = sys.stdin.read().splitlines()
    if not data:
        print(-1)  # 如果没有输入数据,直接输出-1
        return
    
    # 解析第一行:草地长n、宽m、计划数量q
    first_line = data[0].split()
    n = int(first_line[0])
    m = int(first_line[1])
    q = int(first_line[2])
    
    idx = 1  # 当前读取行索引
    grid_init = []  # 存储草地初始状态
    for _ in range(n):
        # 读取n行草地初始状态
        grid_init.append(data[idx].strip())
        idx += 1
        
    plans = []  # 存储所有燃放计划
    for _ in range(q):
        plan_matrix = []  # 存储单个计划
        for _ in range(n):
            # 读取每个计划的n行数据
            plan_matrix.append(data[idx].strip())
            idx += 1
        plans.append(plan_matrix)  # 将计划添加到列表中
    
    # 定义函数:检查选定计划子集S是否满足条件
    def check_subset(S):
        # 遍历草地每个位置
        for i in range(n):
            for j in range(m):
                # 如果当前位置有杂物
                if grid_init[i][j] == '1':
                    # 检查所有选定计划:该位置必须都不是'1'
                    for p_idx in S:
                        if plans[p_idx][i][j] == '1':
                            return False  # 违反条件,返回失败
                # 如果当前位置是空地
                else:
                    found_cover = False
                    # 检查所有选定计划:至少有一个计划该位置是'1'
                    for p_idx in S:
                        if plans[p_idx][i][j] == '1':
                            found_cover = True
                            break
                    # 如果没有计划覆盖该空地
                    if not found_cover:
                        return False  # 违反条件,返回失败
        return True  # 所有位置满足条件

    # 初始化标志和最优子集
    found = False
    best_subset = None
    
    # 从小到大枚举子集大小k (0到q)
    for k in range(0, q + 1):
        # 生成所有大小为k的子集组合
        for subset in itertools.combinations(range(q), k):
            # 检查当前子集是否满足条件
            if check_subset(subset):
                found = True
                best_subset = subset  # 记录满足条件的子集
                break  # 找到即跳出循环(保证最小数量)
        if found:
            break  # 已找到最优解,跳出外层循环
            
    # 输出结果处理
    if not found:
        print(-1)  # 无解情况
    else:
        p = len(best_subset)  # 使用计划数量
        print(p)  # 输出计划数量
        if p > 0:
            # 将子集索引转换为1-based编号并输出
            selected_indices = [str(x + 1) for x in best_subset]
            print(" ".join(selected_indices))

if __name__ == '__main__':
    main()

还没有python的题解,DS花了5分钟写的,这题竟然被标注为简单

全部评论

相关推荐

评论
点赞
收藏
分享

创作者周榜

更多
牛客网
牛客网在线编程
牛客网题解
牛客企业服务