HDOJ 1007 点集中 最近点对
:又是二分,在一个找中间点时没加判断条件,TIL了好多次,后来找到了这个小错误,AC。
学几何以来感觉到二分很强大。昨天晚上10级ACM选拨,想练练手感用二分查找去试着做N的N次方,但是数据太大,WA了。只好老实用对数方法做了。
HDOJ 3868 点集中 周长最小三角形
:杭电OJ不给力,学了这么久几何,唯一一次有可能在OJ比赛中A掉一个几何题,竟然突发状况,OJ爆掉了。赛后再A掉吧(赛后毫无压力地AC了)
RunId : 4210679 Language : G++ Author : ccsu2009021212
Code Render Status : Rendered By HDOJ G++ Code Render Version 0.01 Beta
#include <cmath >
#include<iostream>
#include<stdio.h>
using namespace std;
const double INF = 1E200;
const double EP = 1E-10;
const double PI = acos(-1.0);
struct POINT
{
double x;
double y;
POINT(double a=0, double b=0) { x=a; y=b;} //constructor
}point[100009];
double dist(POINT p1,POINT p2)
{
return sqrt((p1.x-p2.x)*(p1.x-p2.x)+(p1.y-p2.y)*(p1.y-p2.y) );
}
bool cmpx(POINT a,POINT b)
{
return (a.x<b.x) ;
}
bool cmpy(int a,int b)
{
return (point[a].y<point[b].y) ;
}
int ch[100009];
double shortest(int left,int right)//必须先要 sort(point,point+n,cmpx);
{
if( right-left==1)
return dist(point[left],point[right]);
if( right-left==2)
return min(min(dist(point[right],point[right-1]),dist(point[right-1],point[left])),dist(point[left],point[right]));
int mid=(left+right)>>1;
double temp=min(shortest(left,mid),shortest(mid+1,right));
int len=0;
for(int i=mid;i>=left&&temp>=point[mid+1].x-point[i].x;i--)
ch[len++]=i;
for(int i=mid+1;i<=right&&temp>=point[i].x-point[mid].x;i++)
ch[len++]=i;
sort(ch,ch+len,cmpy);
for(int i=0;i<len;i++)
for(int j=i+1;j<len&&(point[ch[j]].y-point[ch[i]].y)<=temp;j++)//这个退出条件很造成可能超时
temp=min(temp,dist(point[ch[j]],point[ch[i]]));
return temp;
}
int main()
{
int n;
while( scanf("%d",&n)!=EOF&&n!=0)
{
for(int i=0;i<n;i++)
scanf("%lf %lf",&point[i].x,&point[i].y);
sort(point,point+n,cmpx);
double ans=shortest(0,n-1)/2.0;
printf("%.2lf\n",ans);
}
}
View Code
RunId : 4236747 Language : G++ Author : ccsu2009021212
Code Render Status : Rendered By HDOJ G++ Code Render Version 0.01 Beta