给定N×M的矩阵A,其中A[1][1]为左上角的元素,A[N][M]为右下角。你需要用下面的伪代码构造另一个N×M的矩阵B。初始时B的各元素均为0。randomInt(a,b)返回一个介于a和b之间(包括a、b)的均匀随机整数,这b−a+1个整数成为返回值的概率是相等的。forx=1toN:fory=1toM:I=randomInt(1,x)J=randomInt(1,y)K=randomInt(x,N)L=randomInt(y,M)给以(I,J)为左上角,(K,L)为右下角的B的子矩阵内的每个元素加上A[x][y];也即,对于满足I≤p≤K且J≤q≤L的所有B[p][q],令其+=A[x][y]由此构造一个有N×M个街区的城市。编号为(i,j)的街区的高度是海平面上B[i][j]。在下了一场降雨量为X的雨之后,所有海拔高度不超过X的街区都被水淹没了。请注意,在上述构造过程中,由于随机性的存在,城市中每个街区的高度并不是确定的值,而是会根据伪代码的运行结果而有所变化。你需要回答Q个询问,每个询问中会给出一个整数k(0<k<N×M)。你需要求出最小的X,使得在下了一场降雨量为X的雨后,被水淹没的街区的数量的期望值不小于k。
SnackDown 2016
- 写回答
- 好问题 0 提建议
- 追加酬金
- 关注问题
- 邀请回答
-
1条回答 默认 最新
- kingbqx 2023-03-14 20:35关注
这是一个比较复杂的问题,需要用到一些数学和算法知识来求解。以下是一个可能的解决方案:
首先,我们可以发现,在一次降雨之后,被水淹没的街区数量是一个随机变量,其期望值可以用线性期望原理来计算。具体而言,每个街区被淹没的概率等于其海拔高度不超过降雨量的概率,即P(h ≤ X),其中h为该街区的海拔高度。因此,被水淹没的街区数量可以表示为:S = ∑(i,j) [h(i,j) ≤ X],其中(i,j)遍历所有街区。
根据线性期望原理,期望值E[S]等于每个街区被淹没的期望值之和,即:E[S] = ∑(i,j) E[h(i,j) ≤ X]。因此,我们只需要计算每个街区被淹没的期望值,然后将它们相加即可得到期望的被淹没街区数量。
接下来,我们考虑如何计算E[h(i,j) ≤ X]。由于伪代码中使用了随机数生成器来构造城市的高度分布,因此我们必须先找到这个分布的数学性质,才能进一步计算期望。
假设A[x][y]表示第x行、第y列的街区在伪代码运行结束后的高度,我们可以观察到以下几个性质:
A[x][y]是一个介于0和N×M之间的均匀随机整数;
对于任意的i ≤ x和j ≤ y,A[i][j]都会对A[x][y]产生影响;
一个街区的海拔高度等于其所在的子矩阵中最大的A值;
对于任意的i ≤ x和j ≤ y,B[i][j]都会受到A[x][y]的影响。
基于上述性质,我们可以得到以下结论:A[x][y]的概率密度函数为:f(z) = 1/(N×M),其中z属于[0,N×M];
A[x][y]与其它元素的影响是等价的,即它们对B中每个街区的影响是相同的;
B[i][j]的概率密度函数可以表示为:g(z) = (1-(z/N×M)^k)^(N×M) ,其中z属于[0,N×M],k为随机变量S的期望值。
注意到这里的k就是题目中给定的参数。我们的目标是要找到最小的X,使得P(S ≥ k) ≥ 0.5。因此,我们可以通过二分查找来逼近X的值。具体而言,我们首先对X进行猜测,然后计算出每个街区被淹没的期望值,相加得到被淹没街区数量的期望值,再与k进行比较。如果期望值大于等于k,则说明当前的X太大,需要缩小;否则说明X太小,需要增大。重复以上步骤,直到找到满足条件的最小X。综上所述,我们可以通过以下步骤来解决这个问题:
计算出每个街区被淹没的期望值E[h(i,j) ≤ X],其中X是一个猜测值;
将所有期望值相加,得到被淹没街区数量的期望值E[S];
3. 如果E[S] >= k,那么将猜测值减小一半,并重复步骤1和2;
4. 如果E[S] < k,那么将猜测值增加一半,并重复步骤1和2;
5. 重复步骤3和4,直到找到一个满足要求的X。下面是一个可能的Python代码实现:
import random # 构造城市 def build_city(N, M): A = [[random.randint(0, N*M) for j in range(M)] for i in range(N)] B = [[0 for j in range(M)] for i in range(N)] for x in range(N): for y in range(M): I = random.randint(0, x) J = random.randint(0, y) K = random.randint(x, N-1) L = random.randint(y, M-1) for i in range(I, K+1): for j in range(J, L+1): B[i][j] += A[x][y] return B # 计算期望淹没街区数量 def expected_flooded_count(city, X): N, M = len(city), len(city[0]) count = 0 for i in range(N): for j in range(M): if city[i][j] <= X: p = (1 - (city[i][j] / (N*M))**N*M)**N*M count += p return count # 二分查找最小的X,使得被淹没街区数量的期望值不小于k def find_X(city, k): lo, hi = 0, N*M while lo < hi: mid = (lo + hi) // 2 count = expected_flooded_count(city, mid) if count >= k: hi = mid else: lo = mid + 1 return lo # 示例用法 N, M = 10, 10 # 城市大小 k = 30 # 询问参数 city = build_city(N, M) X = find_X(city, k) print("最小降雨量为:", X)
解决 无用评论 打赏 举报
悬赏问题
- ¥20 蓝牙耳机怎么查看日志
- ¥15 Fluent齿轮搅油
- ¥15 八爪鱼爬数据为什么自己停了
- ¥15 交替优化波束形成和ris反射角使保密速率最大化
- ¥15 树莓派与pix飞控通信
- ¥15 自动转发微信群信息到另外一个微信群
- ¥15 outlook无法配置成功
- ¥30 这是哪个作者做的宝宝起名网站
- ¥60 版本过低apk如何修改可以兼容新的安卓系统
- ¥25 由IPR导致的DRIVER_POWER_STATE_FAILURE蓝屏