uva 12108特别困学生by小黑python

具体题目及内容详解见我之前的博客: https://blog.csdn.net/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)!!

在此,欢迎大佬们对我的指点与交流

已标记关键词 清除标记
©️2020 CSDN 皮肤主题: 大白 设计师:CSDN官方博客 返回首页