一维最近点对(数轴上)
模版:
#include<bits/stdc++.h>
using namespace std;
const int inf=0x3f3f3f3f;//赋大值
double s[100];
double mn;
double closest(int low,int high)
{
if(low+1==high)
return s[high]-s[low];
if(low+2==high)
return min(s[low+1]-s[low],s[high]-s[low+1]);
int mid=(low+high)>>1;
double ans=min(closest(low,mid),closest(mid+1,high));
if(s[mid+1]-s[mid]<ans) ans=s[mid+1]-s[mid];
return ans;
}
double Random()
{
double result=rand()%10000;
return result*0.01;
}
int main()
{
int n,m;
//随机生成种子值
srand(1);
while(~scanf("%d",&n))
{
for(int i=0;i<n;i++)
{
s[i]=rand()%10000;
printf("%lf ",s[i]);
}
printf("\n");
sort(s,s+n);
for(int i=0;i<n;i++)
printf("%lf ",s[i]);
printf("\n");
printf("%.4lf\n",closest(0,n-1));
}
}
二维(一个平面上)有n个点
求距离两个点之间的最近距离(最近点对)
模版:
#include<bits/stdc++.h>
#define INF 0x3f3f3f3f//取大值
#define N 100005
using namespace std;
typedef long long LL;
const int MAXN = 100005;
struct Point
{
LL x,y;
};
int numOfPoint;
Point points[MAXN], TempMerge[MAXN];
Point ansPoint1, ansPoint2;
LL closest;
int cmp_X(Point A, Point B)
{
if(A.x != B.x) return A.x < B.x;
return A.y < B.y;
}
int cmp_Y(Point A, Point B)
{
if(A.y != B.y) return A.y < B.y;
return A.x < B.x;
}
#define distance(A, B) (A.x-B.x)*(A.x-B.x)+(A.y-B.y)*(A.y-B.y)
LL calculateTheClosest(int low, int high)
{
for(int i=low;i<=high;i++)TempMerge[i-low] = points[i];
sort(TempMerge, TempMerge+(high-low+1), cmp_Y);
for(int i=0;i<high-low;i++)
{
for(int j=i+1;j<=i+6 && j<=high-low;j++)
{
LL calc = distance(TempMerge[i], TempMerge[j]);
if(calc < closest)
{
closest = calc;
ansPoint1 = TempMerge[i];
ansPoint2 = TempMerge[j];
}
}
}
return closest;
}
LL findTheClosest(int left, int right)
{
if(left>=right)
return INF;
int mid = (left+right)>>1;
LL leftAns = findTheClosest(left, mid);
LL rightAns = findTheClosest(mid+1, right);
LL ans = min(leftAns, rightAns);
int low = left, high = mid+1;
while(distance(points[low], points[mid])>ans)
low++;
while(high <= right && distance(points[high], points[mid])<=ans)
high++;
ans = min(ans, calculateTheClosest(low, high-1));
return ans;
}
LL data[100005];
LL sum[100005];
int main()
{
LL n;
scanf("%lld",&n);
for(LL i=0;i<n;i++)
scanf("%lld",&data[i]);
sum[0]=data[0];
for(LL i=1;i<n;i++)
sum[i]=sum[i-1]+data[i];
memset(points,0,sizeof(points));
closest = INF;
for(LL i=0;i<n;i++)
{
points[i].x=i;
points[i].y=sum[i];
}
sort(points,points+n,cmp_X);
LL ans=findTheClosest(0,n-1);
printf("%lld\n",ans);
return 0;
}