当前位置: 首页 > news >正文

P11232 [CSP-S 2024] 超速检测(民间数据)

原题链接​​​​​​

来分析这道题,题中所说由于是匀加速直线运动,所以超速的区间一定是连续的,而且还可以被计算出来,但是要注意区间的开闭。

我们可以把超速的区间变为测速仪的分布区间。

这道题可以通过多区间贪心来实现:一条长线段上有若干条短线段(可以重复也可以不完全覆盖长线段),请在长线段上选取尽可能少的点,使得每条短线段上(含端点)都有被选取的点。

贪心实现:按照右端点排序(从小到大),然后在尽可能少的右端点初开测速仪。

代码+注释:

#include<bits/stdc++.h>
using namespace std;
const int N = 1e5 + 2, L = 1e6 + 2;
int t, n, m, l, V, tmp, ans1, ans2;
int d[N], v[N], a[N], p[N];
int lft[L], rgt[L]; //距离最近的测速仪编号
int ld[N], rd[N]; //每辆车超速区间的左、右端点
int g[N]; //所有超速的车的编号
int id; //后面贪心用的
bool cmp(int x, int y) {return rd[x] < rd[y];
}
void solve() {//1.常规读入+初始化ans1 = ans2 = 0, id = -1;cin >> n >> m >> l >> V;for (int i = 1; i <= n; ++i)cin >> d[i] >> v[i] >> a[i];for (int i = 1; i <= m; ++i) {cin >> p[i];lft[p[i]] = rgt[p[i]] = i; //这一行是2.的步骤,提前到这}//2.预处理距离最近的测速仪编号p[0] = 0, p[m + 1] = l + 1;for (int i = 0; i <= m; ++i)for (int j = p[i] + 1; j < p[i + 1]; ++j)lft[j] = i, rgt[j] = i + 1;//3.计算每辆车的超速区间(本题核心)for (int i = 1; i <= n; ++i) {if (d[i] > p[m]) continue; //如果驶入的位置之后没有测速仪就不理它了if (a[i] == 0) {if (v[i] > V) {g[++ans1] = i;ld[i] = rgt[d[i]];rd[i] = m;} //一开始就超速} else if (a[i] > 0) {if (v[i] > V) {g[++ans1] = i;ld[i] = rgt[d[i]];rd[i] = m;} //一开始就超速else {tmp = V * V - v[i] * v[i];if (tmp % (2 * a[i]) == 0) {tmp = d[i] + tmp / (2 * a[i]); //当车行驶到这里时提速到Vif (tmp < p[m]) {g[++ans1] = i;ld[i] = rgt[tmp + 1];rd[i] = m;} //在p[m]处恰好提速到V是不算的} else {tmp = d[i] + tmp / (2 * a[i]) + 1;if (tmp <= p[m]) {g[++ans1] = i;ld[i] = rgt[tmp];rd[i] = m;}}} //加速了一会儿才超速} else {if (v[i] > V) {tmp = v[i] * v[i] - V * V;if (tmp % (-2 * a[i]) == 0) {tmp = d[i] + tmp / (-2 * a[i]);if (tmp > p[m]) {g[++ans1] = i;ld[i] = rgt[d[i]];rd[i] = m;} else {ld[i] = rgt[d[i]];rd[i] = lft[tmp - 1];if (rd[i] >= ld[i]) g[++ans1] = i;}} else {tmp = d[i] + tmp / (-2 * a[i]);if (tmp >= p[m]) {g[++ans1] = i;ld[i] = rgt[d[i]];rd[i] = m;} else {ld[i] = rgt[d[i]];rd[i] = lft[tmp];if (rd[i] >= ld[i]) g[++ans1] = i;}}} //一开始超速,后面减速}}//4.计算最少需要开启的测速仪数量(贪心)sort(g + 1, g + 1 + ans1, cmp);for (int i = 1; i <= ans1; ++i)if (ld[g[i]] > id) {id = rd[g[i]];++ans2;} //如果左端点没有被覆盖到,那就在右端点覆盖cout << ans1 << " " << m - ans2 << endl;
}
int main() {cin >> t;while (t--) solve();return 0;
}


http://www.mrgr.cn/news/59977.html

相关文章:

  • python对文件的读写操作
  • Python数据分析——Numpy
  • Redis_写时复制(cow)
  • 别名联想路径,前端项目输入@/自动出提示目录和文件
  • PG数据库之事务处理
  • 第六十二周周报 HestGCL
  • 【热门主题】000010 深入 Vue.js 组件开发
  • 【办公类-53-14】2024年9月周计划系列优化(5天、6天、7天模版)
  • vue3 debounce 作用:函数会从其被调用时延迟执行到调用结束的这段时间内,如果该函数被再次调用,则重新计算时间。
  • 使用 BERT 和逻辑回归进行文本分类及示例验证
  • 在数据库访问中,使用localhost、127.0.0.1和IP地址有什么差异
  • Java 中的 队列(Queue)与双端队列(Deque)
  • Host Key Verification Failed
  • 软件测试学习总结
  • 【Python】为Pandas加速(适合Pandas中级开发者)
  • PG数据库之数据类型入门
  • 【mysql】什么是当前读
  • JMeter 接口和性能测试常用函数最全解析!
  • ICP之点云特征计算
  • 只需要写几行 SQL,这个网站就搭好了?
  • shell脚本每日一练4
  • GitHub 上传项目保姆级教程
  • 【C++单调栈 贡献法】907. 子数组的最小值之和|1975
  • python基于django线上视频学习系统设计与实现_j0189d4x
  • 【Linux系统编程】——Linux入门指南:从零开始掌握操作系统的核心(指令篇)
  • 基于SpringBoot的中药材进存销管理系统设计与实现