离散化
例题:P3138 [USACO16FEB] Load Balancing S
有一个直接的做法,考虑整个平面里的每一个点
- 左下:
- 左上:
- 右下:
- 右上:
而四个区域的奶牛数量可以借助二维前缀和来计算。
但是,题目中的坐标范围是
注意到
离散化的一种做法是将需要离散化的数值放入一个数组,对其排序,当需要知道某个原始值经过离散化之后映射成多少时利用二分查找返回其在有序数组中的位置即可。
#include <cstdio> #include <algorithm> using std::sort; using std::lower_bound; using std::max; using std::min; const int N = 2005; // 每个坐标有两个数值,离散化之后最多2000个点 int x[N], y[N], d[N], cnt, sum[N][N]; int getid(int num) { // 通过二分查找获取离散化之后的值 return lower_bound(d + 1, d + cnt + 1, num) - d; } int main() { int n; scanf("%d", &n); cnt = 2 * n; for (int i = 1; i <= n; i++) { scanf("%d%d", &x[i], &y[i]); d[i] = x[i]; d[i + n] = y[i]; } sort(d + 1, d + cnt + 1); // 将涉及到的数据排序以便离散化 for (int i = 1; i <= n; i++) { int xid = getid(x[i]), yid = getid(y[i]); sum[xid][yid]++; } // 离散化后预处理二维前缀和 for (int i = 1; i <= cnt; i++) for (int j = 1; j <= cnt; j++) sum[i][j] += sum[i - 1][j] + sum[i][j - 1] - sum[i - 1][j - 1]; int ans = n; for (int i = 1; i <= cnt; i++) for (int j = 1; j <= cnt; j++) { int m = 0; int dl = sum[i][j]; m = max(m, dl); // 左下 int ul = sum[i][cnt] - dl; m = max(m, ul); // 左上 int dr = sum[cnt][j] - dl; m = max(m, dr); // 右下 int ur = n - dl - ul - dr; m = max(m, ur); // 右上 ans = min(ans, m); } printf("%d\n", ans); return 0; }
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 分享一个免费、快速、无限量使用的满血 DeepSeek R1 模型,支持深度思考和联网搜索!
· 基于 Docker 搭建 FRP 内网穿透开源项目(很简单哒)
· ollama系列1:轻松3步本地部署deepseek,普通电脑可用
· 按钮权限的设计及实现
· 【杂谈】分布式事务——高大上的无用知识?