每日一题 | 灾后重建问题

时间:2022-07-23
本文章向大家介绍每日一题 | 灾后重建问题,主要内容包括其使用实例、应用技巧、基本知识点总结和需要注意事项,具有一定的参考价值,需要的朋友可以参考一下。

昨日题解

每日一题 | 土豪割草问题

出自codeforces联想杯的校园邀请赛,链接:https://codeforces.com/gym/102623/problem/H

昨天的问题看起来很简单,只是一个寻常的模拟题,只要我们照着题目的要求操作就可以了。但是当你实际这么做你会发现是不行的,原因也很简单,因为数据的范围太大了。草地中草的生长速率以及割草的最长时间都是这个量级,在这个量级下线性的复杂度都是不可以接受的。

所以我们被逼无奈必须对算法进行优化,我们想到k的范围是3*10⁵,要小上不少,我们很容易可以想到我们可以用一个二维数组记录每个区域的草上次被割的时间,再对这些割草操作进行排序。这样我们每次割草的时候只需要用相邻两次割草的时间间隔乘上草的生长速度就是我们收割的草的数量。

贴一下超时的代码:

import math
 
weed = [[0 for _ in range(505)] for _ in range(505)]
rate = [[0 for _ in range(505)] for _ in range(505)]
 
n, m, k = map(int, input().split(' '))
 
for i in range(1, n+1):
    cur = list(map(int, input().split(' ')))
    for j in range(1, m+1):
        rate[i][j] = cur[j-1]
 
 # 记录所有割草的操作
operations = []
for _ in range(k):
    o, x, t = input().split(' ')
    operations.append((o, int(x), int(t)))
 
operations = sorted(operations, key=lambda x: x[2])
 
ret = 0
 
for o, x, t in operations:
    # 枚举被割的行或列
    if o == 'r':
        for j in range(1, m+1):
            ret += rate[x][j] * (t - weed[x][j])
            weed[x][j] = t
            ret = ret % 998244353
    else:
        for i in range(1, n+1):
            ret += rate[i][x] * (t - weed[i][x])
            weed[i][x] = t
            ret = ret % 998244353
 
print(ret)

那还有什么办法吗?当然是有的,不过藏得比较深,我们来思考一个问题,每块面积上的草的成长速度但是各不相同,但是都是固定的,不会随着时间变化而变化。其实我们不管这当中收割了多少次,我们只需要知道最后一次收割的时间就可以了,因为这当中草都是一直在生长的,收割草并不会影响草的生长。

这道题并没有用到什么特殊的算法,完全是思维题,考验的就是思维的能力以及问题的分析和求解,适合每一个人挑战。

附上AC代码:

import math
 
R = [0 for _ in range(505)]
C = [0 for _ in range(505)]
rate = [[0 for _ in range(505)] for _ in range(505)]
 
n, m, k = map(int, input().split(' '))
 
for i in range(1, n+1):
    cur = list(map(int, input().split(' ')))
    for j in range(1, m+1):
        rate[i][j] = cur[j-1]
 
 
 # 记录每行和每列收割的时间
for _ in range(k):
    o, x, t = input().split(' ')
    x, t = int(x), int(t)
    if o == 'r':
        R[x] = t
    else:
        C[x] = t
 
 
ret = 0
 
for i in range(1, n+1):
    for j in range(1, m+1):
        ret = ret + max(R[i], C[j]) * rate[i][j]
        ret = ret % 998244353
 
print(ret)

今日问题

灾后重建问题

我们希望在重建花费最小的基础上使得重建后的城市当中的最大度最小,对于图当中的一个点来说,度表示与它有直接边相连的其他点的数量。我们要图当中度最大的点的度最小。

样例

- END -