HDU 4631
来源:互联网 发布:2m数据测试仪 编辑:程序博客网 时间:2024/05/20 03:04
题意 : 平面上n个点依次加入,然后让你不断求任何两个点的最小距离。
题解 : 看到这个题目我们不难想到求平面上的最近点对的做法 先将加入的所有点的x按照从小到大排序, 每次向两边扫描x距离小于 当前最小值的所有点,不断更新当前最小值,直到出现0就停止这种操作,关键是怎样每次都保证x有序呢 ? 当然是不断加入 multiset 中 (因为点可以重复). 我们不难发现这样可以剪枝剪掉大量无用的点,但是如果所有的x 都是同一个的话,肯定就会达到最坏复杂度,但是这个题目的数据显然是随机出现的点,所以这种情况不可能出现,所以这种算法大概的复杂度也就很低,也可以认为不是水过去的吧 当然 kd tree 也是可以的
#include <cstdio>#include <set>#include <iostream>#include <algorithm>using namespace std;const int maxn = 500000 + 10;const long long INF = (1LL<<60);int n, x[maxn], y[maxn];struct Point{ int x; int y; bool operator < (const Point& e) const{ return x < e.x; }};void read(int *a){ int A, B, C, i; a[0] = 0; scanf("%d%d%d", &A, &B, &C); for(i = 1; i <= n; i++){ a[i] = ((long long)a[i-1] * A + B) % C; }}long long solve(){ int i; long long Min = INF, ret = 0; multiset <Point> se; se.clear(); Point v; v.x = x[1]; v.y = y[1]; se.insert(v); for(i = 2; i <= n; i++){ v.x = x[i]; v.y = y[i]; multiset<Point>::iterator p = se.lower_bound(v), iter; for(iter = p; iter != se.end(); iter++){ //从p开始,一直到se.end()前一个位置 long long dx = v.x - iter->x; dx *= dx; if(dx >= Min) break; //剪枝 long long dy = v.y - iter->y; dy *= dy; Min = min(Min, dx + dy); } for(iter = p; iter != se.begin();){ //从p的上一个位置开始,一直算完se.begin() iter --; long long dx = v.x - iter->x; dx *= dx; if(dx >= Min) break; //剪枝 long long dy = v.y - iter->y; dy *= dy; Min = min(Min, dx + dy); } ret += Min; se.insert(v); } return ret;}int main() { int T; scanf("%d", &T); while(T--) { scanf("%d", &n); read(x); read(y); printf("%lld\n", solve()); } return 0;}
阅读全文
0 0
- HDU 4631
- HDU 4631 set维护
- hdu
- hdu
- HDU
- hdu ()
- hdu
- hdu
- HDU
- HDU
- hdu
- hdu
- HDU
- Hdu
- hdu
- hdu-
- hdu
- hdu
- 解决web项目无法部署到eclipse配置的本地tomcat
- Spark Streaming
- hibernate多对一
- 计算机网络 学习摘要(5)
- 字符编码方式
- HDU 4631
- JavaScript 正则表达式和全局对象
- linux 编译安装amqp
- cs231n notes:Python Numpy Tutorial
- 详解zabbix安装部署(Server端篇)
- ISFP职业规划,“做事情想一出是一出,不行了再换”的28岁ISFP女孩
- RxJava
- VTK图形处理之自定义纹理映射Filter
- 设计模式六大原则(3):依赖倒置原则