具体题目及内容详解见我之前的博客: https://blog.youkuaiyun.com/qq_37418807/article/details/94401447
以下是python代码:
#方法一:每次循环计算清醒人数
import copy #引入copy包
n = int(input("请输入人数和状态:"))
students = [] #students链表,里面每个小链表表示每一个同学ex: [[1,2,3],[2.1.2],[3.2.1]]
for i in range(n): #初始化学生状态
student = input()
a,b,c = [int(j) for j in student.split()] #获取每一行输入,得到a,b,c
students.append([a,b,c]) #添加至列表
first = copy.deepcopy(students) #此处有陷阱,必须是深层拷贝,记录初始状态,检查是否进入死循环(全班不会苏醒)
time = 1 #初始化时间计数变量
while(True):
wake = 0 #初始化wake变量,记录清醒的人
for i in range(n): #计算wake的人
if students[i][2]<=students[i][0]:
wake += 1
if wake == n: #全班都苏醒了则break
print("{}分钟后全班醒".format(time))
break
f = False #检测人数是否满足睡觉条件
if wake < n - wake:
f = True
pass
for i in range(n): #进行这一秒的操作
a,b,c =[int(m) for m in students[i]] #获取每个学生的a,b,c
if c == a+b or (c == a and not f): #两种情况: 1. c到周期的末尾 2. 人数不允许睡觉的情况下,到达了即将睡觉的临界点
c = 0 #c归零
c += 1 #c状态向后移
students[i][2] = c #c的结果传回students列表
pass
if students == first: #与初始状态一致,则进入了死循环
print("全班都死了!")
break
time += 1 #时间的流逝
pass
#方法二:通过sleep全局变量动态计算当前时间的睡觉人数
import copy
students = []
n = int(input("请输入学生的个数:")) #学生个数n
sleep = 0 #初始化睡觉人数为0
time = 1 #time值初始化为1
for i in range(n): #初始化学生的状态
s = input() #将学生状态通过输入字符串接收
students.append([int(a) for a in s.split()])
if students[i][2] > students[i][0]:
sleep += 1 #计算初始化的睡觉人数
first = copy.deepcopy(students) #深度拷贝初始的学生状态数组,判断是否进入死循环,此处有坑,后面详解
while(True):
f = False
if sleep <= n - sleep: #检查睡觉人数是否满足要求
f = True
for student in students: #改变学生的状态指针
[a,b,c] = student
if c == a: #到达睡眠临界值,检查是否满足睡眠要求
if f: #不满足要求
c = 0
else: #满足要求
sleep += 1
elif c == a+b: #c到达了周期末尾,指针回零,学生清醒
c = 0
sleep -= 1
c += 1 #状态指针后移
student[2] = c
time += 1
if not sleep:
print("{}分钟后全班醒了!".format(time))
break
if students == first: #进入状态死循环
print("全班都死了!")
break
其中用到了copy库,其中遇到了一些坑:
python虽然简洁好用,但是在变量的引用上也比较难懂
a.
import copy
a = [1,2,3]
b = a
a[0] = 5
print(b)
运行结果: [5, 2, 3];
a是一个列表对象,变量a保存的并不是列表本身,而是一个地址索引。。a=b导致b和a指向的是同一个列表。。除非写成a = [1,2,3] b = [1,2,3],这样b和a指向的不是一个地址空间了。
b.
a = [1,2,3]
b = a[:]
a[0] = 5
print(b)
运行结果:[1, 2, 3];
这里的a[:]操作表示获取a中的数据,所以b和a并不指向同一个地址空间
c.
a = [1,2,3]
b = a.copy()
a[0] = 5
print(b)
运行结果:[1, 2, 3];
这里的copy函数a[:]作用类似
d.
a = [[1,2,3],[4,5,6]]
b = a[:]
a[0] = [4,5,6]
print(b)
a = [[1,2,3],[4,5,6]]
b = a.copy()
a[0][0] = 8
print(b)
运行结果都是:[[8, 2, 3], [4, 5, 6]]
我们明明拷贝的是数据啊,我们修改了a,但为什么a和b还是相等啊???原因很简单,因为a不再是简单一维列表了,而是多维列表了。我们通过copy函数或者a[:]操作,只是copy了列表的浅层数据,而浅层的数据则是深层数据的地址索引,相当于copy的还是地址索引,所以我们想要修改深层数据值时,深层数据的地址仍然没变。所以就会出现a和b同时修改的现象了。如果想要深层copy一个多维列表a,可以使用copy.deepcopy(a)!!
在此,欢迎大佬们对我的指点与交流