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

UVa11607 Cutting Cakes

UVa11607 Cutting Cakes

  • 题目链接
  • 题意
  • 分析
  • AC 代码

题目链接

  UVa11607 Cutting Cakes

题意

  平面上有n(n≤1 500)个点,其中没有3 点共线。另外有m(m≤700 000)条直线,你的任务是对于每条直线,输出3 个数p, q, r,其中p 和q 为该直线两侧的点数(p≤q),r 是直线穿过的点数。

分析

  本题限时6s,还是比较宽松的,直接用分块法能通过,比如把 n 个点集分成 8×88\times 88×8 块。
  其次,可以构建四叉树求解。先取 mid=n/2mid = n /2mid=n/2 处的点 p,根据其坐标得到划分轴,再遍历所有点 t 进行划分,t 在坐标轴上则存到当前结点数据中,不在坐标轴上则按照其所在象限存入四棵子树的数据中并递归构建子树。此后只需要从根结点递归查询:先求根结点数据的首个点与直线两端点形成的三角形有向面积 s(s>0s > 0s>0 则 ++p;s=0s = 0s=0 则 ++r;s<0s < 0s<0 则 ++q),其它数据点也都求有向面积后进行 p、q、r 进行统计。然后可以利用首个点的有向面积 s 分类讨论四个子结点的计数:s = 0 时,左上象限子结点内的数据全部统计给 p,右下象限子结点内的数据全部统计给 q,然后左下、右上两个象限的子结点进行递归查询;s > 0 时,左上象限子结点内的数据全部统计给 p,然后左下、右下、右上三个象限的子结点进行递归查询;s < 0 时右下象限子结点内的数据全部统计给 q,然后左下、左上、右上三个象限的子结点进行递归查询。

AC 代码

#include <iostream>
#include <algorithm>
using namespace std;#define M 10000
#define N 1510
#define B 8
int x[N], y[N], u[N], v[N], x1, y1, x2, y2, dx1, dy1, dx2, dy2, vx, vy, a, b, m, n, p, r, kase = 0;int cross(int x1, int y1, int x2, int y2) {return x1*y2 - x2*y1;
}struct {int b[N], bx1, by1, bx2, by2, by4, c;void add(int i) {b[c++] = i;if (c == 1) bx1 = bx2 =x[i], by1 = by2 = y[i];else bx1 = min(bx1, x[i]), bx2 = max(bx2, x[i]), by1 = min(by1, y[i]), by2 = max(by2, y[i]);}void query() {int cc = cross(vx, vy, bx1 - x1, by1 - y1); bool e = cc < 0, f = cc == 0, g = cc > 0;cc = cross(vx, vy, bx2 - x1, by1 - y1); e = e || cc < 0; f = f || cc == 0; g = g || cc > 0;cc = cross(vx, vy, bx1 - x1, by2 - y1); e = e || cc < 0; f = f || cc == 0; g = g || cc > 0;cc = cross(vx, vy, bx2 - x1, by2 - y1); e = e || cc < 0; f = f || cc == 0; g = g || cc > 0;if (f || (e && g)) {for (int i=0; i<c; ++i) {cc = cross(vx, vy, x[b[i]]-x1, y[b[i]]-y1);if (cc > 0) ++p;else if (cc == 0) ++r;}} else if (g) p += c;}
} s[B][B];void query() {x1 = (x1 + dx1) % M; y1 = (y1 + dy1) % M; x2 = (x2 + dx2) % M; y2 = (y2 + dy2) % M;if (x1 == x2 && y1 == y2) y2 = (y1 + 1) % M;p = 0; r = 0; vx = x2 - x1; vy = y2 - y1;for (int i=0; i<B; ++i) for (int j=0; j<B; ++j) s[i][j].query();cout << min(p, n-r-p) << ' ' << max(p, n-r-p) << ' ' << r << endl;
}void solve() {cin >> n;for (int i=0; i<n; ++i) cin >> x[i] >> y[i], u[i] = x[i], v[i] = x[i];sort(u, u+n); sort(v, v+n); a = unique(u, u+n) - u; b = unique(v, v+n) - v;for (int i=0; i<B; ++i) for (int j=0; j<B; ++j) s[i][j].c = 0;for (int i=0, j=(a+B-1)/B, k=(b+B-1)/B; i<n; ++i)s[(lower_bound(u, u+a, x[i]) - u) / j][(lower_bound(v, v+b, y[i]) - v) / k].add(i);cout << "Case #" << ++kase << ':' << endl;cin >> m >> x1 >> y1 >> x2 >> y2 >> dx1 >> dy1 >> dx2 >> dy2;while (m--) query();
}int main() {ios::sync_with_stdio(false); cin.tie(0); cout.tie(0);int t; cin >> t;while (t--) solve();return 0;
}
http://www.dtcms.com/a/353114.html

相关文章:

  • Java垃圾回收器:从SerialGC到G1的演进/速通
  • 流程控制语句(1)
  • 如何检查 Linux 系统的内存使用情况
  • vue2实现背景颜色渐变
  • 【目标检测】论文阅读4
  • 分布式2PC理论
  • 大脑的藏宝图——神经科学如何为自然语言处理(NLP)的深度语义理解绘制新航线
  • (11)用于无GPS导航的制图师SLAM(一)
  • 【Android】原安卓生态发起网络GET请求 Post请求
  • 【87页PPT】智慧方案智慧校园智能化综合建设方案(附下载方式)
  • Linux操作系统—进程
  • 基于Prometheus Pushgateway与Alertmanager的自定义指标监控与告警实践指南
  • 【HTML】隐藏滚动条但保留功能
  • 年度优质会议推荐:【西安石油大学主办|IEEE出版|往届均EI】第七届智能控制、测量与信号处理国际学术会议 (ICMSP 2025)
  • Playwright进阶指南 (6) | 自动化测试实战
  • 从 GRIT 到 WebUI:Chromium 内置资源加载与前端展示的完整链路解析
  • 寻找AI——初识墨刀AI
  • 【FPGA】VGA显示-贪吃蛇
  • oracle 表空间扩容(增加新的数据文件)
  • 浅聊达梦数据库物理热备的概念及原理
  • VESA时序检测模块设计verilog实现
  • 力扣hot100:字母异位词分组和最长连续序列(49,128)
  • Ansible的介绍+ansible平台部署
  • 互联网大厂Java面试深度解析:从基础到微服务云原生的全场景模拟
  • 公开课程 | 大规模图数据管理与分析 第二讲:图的度量、性质与生成模型
  • redbook的判断完美数
  • 销售数据分析平台
  • LeetCode hot 100 每日一题(18)——206.反转链表
  • 开源 | 推荐一套企业级开源AI人工智能训练推理平台(数算岛):完整代码包含多租户、分布式训练、模型市场、多框架支持、边缘端适配、云边协同协议:
  • 高并发写入、毫秒级查询——盘古信息携手 TDengine 时序数据库解决六大技术挑战