自用--最近对问题(分治法)P68

#include<iostream>
#include<cmath>
using namespace std;

//定义结构体point标识集合S中点的坐标
struct point{
	int x,y;
}; 

//函数distance求两点之间的距离
double Distance(point a,point b){

	return sqrt((a.x-b.x)*(a.x-b.x)+(a.y-b.y)*(a.y-b.y));
} 
//对数组进行划分
int Partition(point r[],int first,int end){
	int i=first;
	int j=end;//初始化带划分区域
	while(i<j){
		//扫描右侧
		while(i<j&&r[i].y<=r[j].y){
			j--;
		} 
		if(i<j){ //将较小记录交换在前面 
			int temp=r[i].y;
			r[i].y=r[j].y;
			r[j].y=temp;
			i++;
		}
		//扫描左侧 
		while(i<j&&r[i].y<=r[j].y){
			i++;
		}
		if(i<j){ //将较大记录放在后面 
			int temp=r[i].y;
			r[i].y=r[j].y;
			r[j].y=temp;
			j--;
		}
	} 
	return i; 
}
//快速排序 
void QuickSort(point r[],int first,int end){
	int pivot;
	if(first<end){
		pivot=Partition(r,first,end);//划分,pivot是轴值再序列中的位置
		//cout<<pivot<<endl;
		QuickSort(r,first,pivot-1);
		QuickSort(r,pivot+1,end);
	} 
}

//函数Closest实现求最近对的距离
double Closest(point S[],int low,int high){
	double d1,d2,d3,d;
	//(x1,y1)..(xm,ym)的最近对距离  (xm,ym)..(xn,yn)的最近对距离
	//d min{d1,d2} 两个区间内的点的最近对距离d3
	int mid,i,j,index;
	point P[10];//存放点集合p1和p2
	if(high-low==1){//只有两个点,直接返回两点之间的距离 
		
		return Distance(S[low],S[high]);
	}
	if(high-low==2){//只有三个点,求最近对距离 
		d1=Distance(S[low],S[low+1]);
		d2=Distance(S[low+1],S[high]);
		d3=Distance(S[low],S[high]);
		if((d1<d2)&&(d1<d3)){
			return d1;
		}
		else if(d2<d3){
			return d2;
		}
		else{
			return d3;
		}
	}
	//如果是有很多很多点的点集
	//1.划分中位数
	mid=(low+high)/2;
	//2.递归计算左边
	d1=Closest(S,low,mid);
	//3.递归计算右边
	d2=Closest(S,mid+1,high);
	//4.获取最小值
	if(d1<=d2){
		d=d1;
	}
	else{
		d=d2;
	}
	//5.确定集合P1、P2
	index=0;
	//5.1如果x<=xm&&x>=xm-d放入p1中
	for(i=mid;((i>=low)&&((S[mid].x-S[i].x)<d));i--){
		P[index++]=S[i];
	}
	//5.2如果x>xm&&x<=xm+d放入p2中
	for(i=mid+1;((i<=high)&&((S[i].x-S[mid].x)<d));i++){
		P[index++]=S[i];
	}
	//5.3将集合p1、p2按照y坐标升序排列 
	QuickSort(P,0,index-1);
	//5.4依次处理集合P1和P2中的点
	for(i=0;i<index;i++){
		for(j=i+1;j<index;j++){
			if((P[j].y-P[i].y)>=d){
				break;
			}
			else{
				d3=Distance(P[i],P[j]);
				if(d3<d)
					d=d3;
			}
		}
	} 
	//6.计算并返回最近距离 
	return d;
} 

int main(){
	int n;
	cin>>n;
	point S[n];
	cout<<"input:"<<endl;
	int i=0;
	while(i<n){
		cin>>S[i].x>>S[i].y;
		i++;
	}
	
	//point S[],int low,int high
	int low=0;
	int high=n-1;
	double sum=0;
	sum=Closest(S,low,high);
	cout<<sum;
	return 0;
} 

回顾:

结构体

  • struct 结构体名 变量名
  • struct 结构体名 变量名 = {成员1值,成员2值}
  • 定义结构体时顺便创建变量
//结构体定义
struct student
{
	//成员列表
	string name;		//姓名
	int age;			//年龄
	int score;			//分数
}stu3;					//结构体变量创建方式3
struct student stu1;//struct 关键字可以省略不写

	stu1.name = "张三";
	stu1.age = 18;
	stu1.score = 100;
struct student stu2 = { "李四",19,60 };

结构体数组

struct 结构体名 数组名[元素个数] = { {}, {}, .....{} }

参考:(20条消息) C++结构体详解_江湖孤隐客的博客-CSDN博客_c++结构体icon-default.png?t=M85Bhttps://blog.csdn.net/qq_51534890/article/details/118637720?ops_request_misc=%257B%2522request%255Fid%2522%253A%2522166489258116782390598568%2522%252C%2522scm%2522%253A%252220140713.130102334..%2522%257D&request_id=166489258116782390598568&biz_id=0&utm_medium=distribute.pc_search_result.none-task-blog-2~all~top_positive~default-1-118637720-null-null.142^v51^control,201^v3^control_2&utm_term=C%2B%2B%E7%BB%93%E6%9E%84%E4%BD%93&spm=1018.2226.3001.4187

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值