1 条题解
-
0
详细题解:
问题分析
题目需要处理两个问题:
- 找到从哪个城市出发,小A与小B行驶路程比值最小
- 回答多组查询,计算从指定城市出发在距离限制内的行驶路程
算法思路
1. 预处理最近邻信息
代码使用链表+排序的方法为每个城市找到"最近"和"第二近"的城市:
- 首先对所有城市按海拔排序
- 使用双向链表维护城市关系
- 对于每个城市,比较左右相邻城市确定最近和第二近城市
- 处理完后从链表中删除当前城市
2. 倍增预处理
构建倍增数组
bz[i][j][k]
:bz[i][j][1]
:从城市i出发,走2^j步,小A行驶的总距离bz[i][j][2]
:从城市i出发,走2^j步,小B行驶的总距离bz[i][j][3]
:从城市i出发,走2^j步后到达的城市
状态转移:
bz[j][i][1] = bz[j][i-1][1] + bz[bz[j][i-1][3]][i-1][1]; bz[j][i][2] = bz[j][i-1][2] + bz[bz[j][i-1][3]][i-1][2]; bz[j][i][3] = bz[bz[j][i-1][3]][i-1][3];
3. 查询处理
使用倍增法快速回答查询:
- 从高位到低位尝试跳跃
- 如果跳跃后总距离不超过限制,则累加距离并更新位置
- 最终得到小A和小B的行驶距离
代码关键部分
排序预处理
使用希尔排序对城市按海拔排序,同时维护原始编号映射:
for(i=1;i<=11;i++) for(j=t[i]+1;j<=n;j++){ jj=j; while(jj-t[i]>0&&h[jj]<h[jj-t[i]]){ // 交换海拔和编号映射 tt=h[jj]; h[jj]=h[jj-t[i]]; h[jj-t[i]]=tt; tt=xq[jj]; xq[jj]=xq[jj-t[i]]; xq[jj-t[i]]=tt; tt=xp[xq[jj]]; xp[xq[jj]]=xp[xq[jj-t[i]]]; xp[xq[jj-t[i]]]=tt; jj=jj-t[i]; } }
最近邻计算
for(i=1;i<=n;i++){ aa = h[l[l[xp[i]]]]; // 左左邻居 bb = h[l[xp[i]]]; // 左邻居 cc = h[r[xp[i]]]; // 右邻居 dd = h[r[r[xp[i]]]]; // 右右邻居 // 根据距离规则确定minn[i]和minnn[i] // ... // 从链表中删除当前城市 r[l[xp[i]]] = r[xp[i]]; l[r[xp[i]]] = l[xp[i]]; }
倍增查询
for(j=log2(n);j>=0;j--) if(disa+disb+bz[mmm][j][1]+bz[mmm][j][2]<=x[i]){ disa = disa + bz[mmm][j][1]; disb = disb + bz[mmm][j][2]; mmm = bz[mmm][j][3]; }
复杂度分析
- 预处理: 排序 + 倍增预处理
- 查询:,每组查询
算法优势
使用倍增法将每次查询的时间复杂度从优化到,能够处理,的大数据规模。
- 1
信息
- ID
- 3550
- 时间
- 1000ms
- 内存
- 256MiB
- 难度
- 10
- 标签
- 递交数
- 1
- 已通过
- 1
- 上传者