【20190802】【校招笔试题】瞌睡_网易

问题

小易觉得高数课太无聊了,决定睡觉。不过他对课上的一些内容挺感兴趣,所以希望你在老师讲到有趣的部分的时候叫醒他一下。你知道了小易对一堂课每分钟知识点的感兴趣程度,并以分数量化,以及他在这堂课上每分钟是否会睡着,你可以叫醒他一次,这会使得他在接下来的k分钟内保持清醒。你需要选择一种方案最大化小易这堂课听到的知识点分值。

输入描述:

第一行 n, k (1 <= n, k <= 105) ,表示这堂课持续多少分钟,以及叫醒小易一次使他能够保持清醒的时间。
第二行 n 个数,a1, a2, ... , an(1 <= ai <= 104) 表示小易对每分钟知识点的感兴趣评分。
第三行 n 个数,t1, t2, ... , tn 表示每分钟小易是否清醒, 1表示清醒。

输出描述:

小易这堂课听到的知识点的最大兴趣值。

输入例子1:

输出例子1:

16


思路及解答

# 分析了题目,用了数学思维解决问题。
# 遍历每一个 t (叫醒的时刻),求得当时的知识点分值,最后取最大。
# 分值 = sum(scores * awake) + sum(scores[t:t+k-1]) - sum(scores[t:t+k-1] * awake[t:t+k-1]),把 scores 列表和 awake 列表对应写在一起,就能想明白了。
# 算法复杂度太高,已超时。AC仅仅0.5。
import sys
n, k = map(int, sys.stdin.readline().strip().split())  
scores = sys.stdin.readline().strip().split()   
scores = [int(tmp1) for tmp1 in scores]
awake = sys.stdin.readline().strip().split()
awake = [int(tmp2) for tmp2 in awake]
result = []
for t in range(n):
    res1, res2, res3 = 0, 0, 0
    for i in range(n):
        res1 += scores[i] * awake[i]
    if t + k <= n:
        for j in range(t, t+k):
            res2 += scores[j] * awake[j]
        for m in range(t, t+k):
            res3 += scores[m]
    else:
        for j in range(t, n):
            res2 += scores[j] * awake[j]
        for m in range(t, n):
            res3 += scores[m]
    result.append(res1 + res3 - res2)
print(max(result))

# 略微有所优化,但依旧不起本质性作用。
import sys
n, k = map(int, sys.stdin.readline().strip().split())
scores = sys.stdin.readline().strip().split()
scores = [int(tmp1) for tmp1 in scores]
awake = sys.stdin.readline().strip().split()
awake = [int(tmp2) for tmp2 in awake]
result = 0
start = 0
for index in range(n):   # 不是从头开始遍历,而是从第一个 awake 为0 的时候开始遍历。
    if awake[index]:
        start += 1
    else:
        break
for t in range(n):
    res1, res2, res3 = 0, 0, 0
    for i in range(n):
        res1 += scores[i] * awake[i]
    if t + k <= n:
        for j in range(t, t+k):
            res2 += scores[j] * awake[j]
        for m in range(t, t+k):
            res3 += scores[m]
    else:
        for j in range(t, n):
            res2 += scores[j] * awake[j]
        for m in range(t, n):
            res3 += scores[m]
    tmp = res1 + res3 - res2
    result = tmp if tmp > result else result   # 更新最大值,不存储每个 t 对应的 tmp。
print(result)

# 略微有所优化,依旧不起本质作用。(仅提升到了 0.6)
import sys
n, k = map(int, sys.stdin.readline().strip().split())
scores = sys.stdin.readline().strip().split()
scores = [int(tmp1) for tmp1 in scores]
awake = sys.stdin.readline().strip().split()
awake = [int(tmp2) for tmp2 in awake]
result = 0
start = 0
for index in range(n):    # 从第一个不清醒时刻开始遍历即可。
    if awake[index]:
        start += 1
    else:
        break
for t in range(start, n-k+1):   # 到 t-k 时刻即可,因为后面再遍历,一定不如 n-k 时叫醒知识点值大。
    res1, res2, res3 = 0, 0, 0
    for i in range(n):
        res1 += scores[i] * awake[i]
    for j in range(t, t+k):
        res2 += scores[j] * awake[j]
    for m in range(t, t+k):
        res3 += scores[m]
    tmp = res1 + res3 - res2
    result = tmp if tmp > result else result   # 更新最大值,不存储每个 t 对应的 tmp。
print(result)

 下面参考牛客网友:瞌睡_牛客网

n, k = list(map(int, input().split()))
scores = list(map(int, input().split()))
awake = list(map(int, input().split()))

# 先计算最初所有清醒时刻分值之和,这里做了一个很巧妙的事情:把清醒时刻的分值加了之后,把其分值置零(为了防止后续再次重复加,大吼一声 666!)
initi_score = 0
for i in range(n):
    if awake[i]:
        initi_score += scores[i]
        scores[i] = 0    # 操作666

# 计算因为叫醒他,分值增加的那一部分
max_boost_score = 0
for t in range(n):   # 提前结束循环的条件,注意:不一定是从非清醒状态开始加,见下面测试用例。
    if not awake[t]:   # 从非清醒状态叫醒才能最佳
        boost_score = sum(scores[t: min(t+k, n)])
        max_boost_score = max(boost_score, max_boost_score)
        if t > n - k + 1:
            break
result = initi_score + max_boost_score
print(result)

知识点

1. 输入输出的问题——用 input 来写(前面一篇用的 sys.stdin.readline())

(参考:瞌睡_网易笔试题_牛客网

# 单行输入,此时有两个元素,用list()把它变成了列表
nk = list(map(int, input().split()))

# 把列表两个元素取出来
n = nk[0]
k = nk[1]

# 再获取第二行输入
a = list(map(int, input().split()))

# 获取下一行输入(即第三行)
t = list(map(int, input().split()))

2. input 的用法

(1) Python2 是 raw_input();Python3 是 input() 。

(参考:Python3 input() 函数

(参考:Python input() 函数

(参考:Python2.x 和 Python3.x 中 raw_input( ) 和 input( ) 区别

(2) Python3 中 input 读出来的一切信息都是 string 类型,若想转换成 int 型,可以用 eval() 或者 int()。

(3) 多个参数输入

① 输入个数确定时

>>> a, b, c = input('...>').split()
...>11 22 33

# 那么有:
    a = '11'
    b = '22'
    c = '33'

② 输入个数不确定时,把它们放在一个列表里面

>>> list = []
>>> list = input('...>').split()
...>11 22 33 44

# 那么有:
    ['11', '22', '33', '44']

(参考:python input 详解

 

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Satisfying

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值