【poj3714】 Raid
来源:互联网 发布:淘宝无名体育发货慢 编辑:程序博客网 时间:2024/06/05 05:52
http://poj.org/problem?id=3714 (题目链接)
现在才搞平面最近点对。。感觉有点尴尬
题意:给出平面上两组点,每组n个,求两组点之间最短距离
Solution1
平面最近点对,分治即可。
将点按横坐标排序,然后每次二分成左边和右边分别计算最小距离,再计算中间的最小距离,这里需要把中间符合条件的点按照纵坐标排序,然后当当前枚举的两点的纵坐标之差大于答案时break,否则会TLE。
代码:
// poj3714#include<algorithm>#include<iostream>#include<cstring>#include<cstdlib>#include<cstdio>#include<cmath>#include<vector>#define inf 2147483640#define LL long long#define free(a) freopen(a".in","r",stdin);freopen(a".out","w",stdout);using namespace std;inline LL getint() { LL x=0,f=1;char ch=getchar(); while (ch>'9' || ch<'0') {if (ch=='-') f=-1;ch=getchar();} while (ch>='0' && ch<='9') {x=x*10+ch-'0';ch=getchar();} return x*f;}const int maxn=1000010;struct point {double x,y;int flag;}p[maxn];int n,tmp[maxn];bool cmpx(point a,point b) { return a.x==b.x ? a.y<b.y : a.x<b.x;}bool cmpy(int a,int b) { return p[a].y==p[b].y ? p[a].x<p[b].x : p[a].y<p[b].y;}double dis(point a,point b) { return sqrt((double)(a.x-b.x)*(a.x-b.x)+(a.y-b.y)*(a.y-b.y));}double solve(int l,int r) { double res=1e60; if (l==r) return res; if (l+1==r) { if (p[l].flag==p[r].flag) return res; return dis(p[l],p[r]); } int mid=(l+r)>>1; res=solve(l,mid); res=min(res,solve(mid+1,r)); int num=0; for (int i=l;i<=r;i++) if (fabs(p[i].x-p[mid].x)<=res) tmp[++num]=i; sort(tmp+1,tmp+num+1,cmpy); for (int i=1;i<=num;i++) for (int j=i+1;j<=num;j++) { if (fabs(p[tmp[i]].y-p[tmp[j]].y)>=res) break; //剪枝 if (p[tmp[i]].flag!=p[tmp[j]].flag) res=min(res,dis(p[tmp[i]],p[tmp[j]])); } return res;}int main() { int T; scanf("%d",&T); while (T--) { scanf("%d",&n); for (int i=1;i<=n;i++) scanf("%lf%lf",&p[i].x,&p[i].y),p[i].flag=0; for (int i=1;i<=n;i++) scanf("%lf%lf",&p[i+n].x,&p[i+n].y),p[i+n].flag=1; n<<=1; sort(p+1,p+1+n,cmpx); printf("%.3f\n",solve(1,n)); } return 0;}
Solution2
hzwer上惊现平面最近点对的随机化算法(貌似是随机分块),于是我就蒯了过来,虽然并不知道为什么可以这样写,但是好像很厉害的样子。
上网搜了下,发现期望复杂度是O(n)的。度娘链接
然而= =:
比分治还跑的慢,坑比东西。
代码:
// poj3714#include<algorithm>#include<iostream>#include<cstdlib>#include<cstring>#include<cstdio>#include<cmath>#define LL long long#define inf 2147483640#define Pi acos(-1.0)#define free(a) freopen(a".in","r",stdin),freopen(a".out","w",stdout);using namespace std;inline LL getint() { int f,x=0;char ch=getchar(); while (ch<='0' || ch>'9') {if (ch=='-') f=-1;else f=1;ch=getchar();} while (ch>='0' && ch<='9') {x=x*10+ch-'0';ch=getchar();} return x*f;}const int maxn=1000010;struct point {double x,y;int flag;}p[maxn];int n,block,m;bool cmp(point a,point b) { return a.x==b.x ? a.y<b.y : a.x<b.x;}point rotate(point a,double x) { return (point){(double)a.x*cos(x)-(double)a.y*sin(x),(double)a.y*cos(x)+(double)a.x*sin(x),a.flag};}double dis(point a,point b) { return sqrt((a.x-b.x)*(a.x-b.x)+(a.y-b.y)*(a.y-b.y));}int main() { int T;scanf("%d",&T); while (T--) { scanf("%d",&n); for (int i=1;i<=n;i++) scanf("%lf%lf",&p[i].x,&p[i].y),p[i].flag=0; for (int i=1;i<=n;i++) scanf("%lf%lf",&p[i+n].x,&p[i+n].y),p[i+n].flag=1; n<<=1; block=(int)sqrt(n); m=n/block+(n%block!=0); double t=rand()/10000; for (int i=1;i<=n;i++) p[i]=rotate(p[i],t); sort(p+1,p+1+n,cmp); double ans=1e60; for (int i=1;i<=m;i++) { int t1=block*(i-1),t2=min(block*i,n); for (int j=t1;j<=t2;j++) for (int k=t1+1;k<=t2;k++) if (p[j].flag!=p[k].flag) ans=min(ans,dis(p[j],p[k])); } printf("%.3f\n",ans); } return 0;}
0 0
- poj3714 Raid
- POJ3714 Raid
- 【poj3714】 Raid
- [POJ3714]Raid
- poj3714——Raid
- poj3714 Raid (分治)
- Raid(poj3714,暴力+剪枝)
- poj3714 Raid(分治法…
- poj3714
- poj3714
- ACM-计算几何之Raid——poj3714
- HDU1007-Quoit Design&POJ3714-Raid(最近点对问题)
- #POJ3714#Raid(不同类最小点对 + 分治)
- poj3714 Raid 找最近点对问题(二)
- POJ3714(分治)
- POJ3714+最近点对
- poj3714 最近点对
- POJ3714-最近点对
- MQTT协议(二):推送篇
- 周志华 《机器学习》之 第十二章(计算学习理论)概念总结
- 二货小易有一个W*H的网格盒子,网格的行编号为0~H-1,网格的列编号为0~W-1。每个格子至多可以放一块蛋糕,任意两块蛋糕的欧几里得距离不能等于2。 对于两个格子坐标(x1,y1),(x2,y2)的
- 为什么你的科目二总是考不过?
- nginx 获取 post body值
- 【poj3714】 Raid
- Codeforces Round #369 (Div. 2) 解题报告(A,B,C)
- Bitmap.Config
- MySQL重置密码
- linux环境变量相关
- 妹子UI之自定义分页控件
- cocos2d-js 重新require JS文件
- Android自定义控件:动画类(五)----属性动画ValueAnimator基本使用
- Java回调机制和Java反射机制理解