蓝桥杯-分考场(python dfs)

一、题目

题目 1874: 蓝桥杯2017年第八届真题-分考场
时间限制: 1Sec 内存限制: 128MB 提交: 1262 解决: 320
题目描述
n个人参加某项特殊考试。
为了公平,要求任何两个认识的人不能分在同一个考场。
求是少需要分几个考场才能满足条件。
输入
第一行,一个整数n(1<n<100),表示参加考试的人数。
第二行,一个整数m,表示接下来有m行数据
以下m行每行的格式为:两个整数a,b,用空格分开 (1<=a,b<=n) 表示第a个人与第b个人认识。
输出
一行一个整数,表示最少分几个考场。
样例输入
5
8
1 2
1 3
1 4
2 3
2 4
2 5
3 4
4 5
样例输出
4

二、思路和代码

思路:一个个分配考试人员,若考场不够,则增加考场,深度有限,可以用dfs。

代码:一直只有80分,但看了看思路和大佬满分的代码差别不大(末尾链接),不知道问题出在哪。


n = int(input())
m = int(input())
ls = list()

# 构建矩阵存储,链式存储的好处在于能够一次遍历完,矩阵存储的好处是可以直接访问
nex = [[0 for _ in range(n+1)] for _ in range(n+1)]

for _ in range(m):
    x, y = input().split()
    x = int(x)
    y = int(y)
    nex[x][y] = 1
    nex[y][x] = 1
# 最优房间数
leastrooms = n
# i, j存放i房间的第j人编号
roomsets = [[0 for _ in range(n+1)] for _ in range(n)]
# 房间里 人的总数
personnum = [0 for _ in range(n)]

# 思路:无向图染色问题,相邻结点不能染相同颜色。
# 考虑用dfs还是bfs首先考虑划分结点的依据,这题是将人放入不同的房间,这就需要确定房间数。
# 用dfs,将人一个个放入房间,此时只要有解就行,而不需要最优解。总体的框架其实是一个每层单结点的bfs
# 第一个深度是一个房间,第二个是两个房间,而实际上要判断每层是否到达结果还是用的dfs。
# 所以这题还是用的dfs
# 思路:若考场不够,则一个个增加考场,深度有限,可以dfs
# 总结:不一定要用set来加快,增加很删除不如一开始就分配好所有空间。


# dfs返回针对当前对第1..cur-1个人的安排至少需要多少个房间
def dfs(cur, rooms):
    global roomsets, n, leastrooms
    if cur > n:
        leastrooms = min(leastrooms, rooms)
        return
    elif rooms >= leastrooms:
        return
    else:
        # 将cur逐个放入房间i中,并记录最优房间数量
        for i in range(rooms):
            # 可以放入
            num = personnum[i]
            k = 0
            for j in range(1, num+1):
                if not nex[cur][roomsets[i][j]]:
                    k += 1
            if k == num:
                # 加入
                personnum[i] += 1
                roomsets[i][personnum[i]] = cur
                dfs(cur+1, rooms)
                # 恢复
                personnum[i] -= 1

        # 放入空房间
        i += 1
        personnum[i] += 1
        roomsets[i][personnum[i]] = cur
        dfs(cur+1, rooms+1)
        # 恢复
        personnum[i] -= 1
        return


dfs(1, 1)
print(int(leastrooms))


别人家的100分代码

  • 0
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值