2020年专业408的算法题

1 题目

定义三元组(a,b,c)(a,b,c均为整数)的距离 D = ∣ a − b ∣ + ∣ b − c ∣ + ∣ c − a ∣ D=|a-b| + |b-c|+|c-a| D=ab+bc+ca。给定3个非空整数集合S1,S2和S3,按升序分别存储在3个数组中。请设计一种尽可能高效的算法,计算并输出所有可能的三元组(a,b,c)( a ∈ S 1 , b ∈ S 2 , c ∈ S 3 a \in S1,b \in S2,c \in S3 aS1,bS2,cS3)中的最小距离。
例如,S1={-1,0,9},S2={-25,-10,10,11},S3={2,9,17,30,41},则最小距离为2,相应的三元组为(9,10,9)。

2 解法一(朴素算法)

思路:
暴力求解所有可能

#include<cstdio>
#include<climits>
#include<cmath>
#include<string.h>
#include<iostream>

int main(){
//S1={-1,0,9},S2={-25,-10,10,11},S3={2,9,17,30,41}
	int S1[] = {-1,0,9};
	int S2[] = {-25, -10, 10, 11};
	int S3[] = {2, 9, 17, 30, 41};
	int res[3];
	//初始化
	memset(res, 0, sizeof(res));
	//计算长度
	int extent1 = sizeof(S1)/sizeof(*S1);
	int extent2 = sizeof(S2)/sizeof(*S2);
	int extent3 = sizeof(S3)/sizeof(*S3);
	//定义int最大值,用于向下比较
	int minLength = INT_MAX; 
	for(int i = 0;i < extent1;i++){
		for(int j = 0;j < extent2;j++){
			for(int k = 0;k < extent3;k++){
				int tempLength = std::abs(S1[i] - S2[j]) + std::abs(S2[j]- S3[k]) + std::abs(S3[k] - S1[i]);
				if(tempLength < minLength){
					minLength = tempLength;
					res[0] = S1[i];
					res[1] = S2[j];
					res[2] = S3[k];
				}
			}
		}
	}
	
	for(auto i:res){
		std::cout<<i<<std::endl;
	}
	
     printf("MinLength is %d", minLength);	
	
	return 0;
}

时间复杂度:O(extent1extent2extent3)

3 解法二

思路(摘自百度文档):
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述在这里插入图片描述
在这里插入图片描述
实现代码:

#include<cstdio>
#include<climits>
#include<cmath>
#include<string.h>
#include<iostream>

#define xIsMin(x, y, z) (((x) <= (y)) && ((x) <= (z)))

int main(){
//S1={-1,0,9},S2={-25,-10,10,11},S3={2,9,17,30,41}
	int S1[] = {-1,0,9};
	int S2[] = {-25, -10, 10, 11};
	int S3[] = {2, 9, 17, 30, 41};
	int res[3];
	memset(res, 0, sizeof(res));
	
	int extent1 = sizeof(S1)/sizeof(*S1);
	int extent2 = sizeof(S2)/sizeof(*S2);
	int extent3 = sizeof(S3)/sizeof(*S3);

	int minLength = INT_MAX, dis;
	int i = 0, j = 0, k = 0; 
	while(i < extent1 && j < extent2 && k < extent3 && minLength > 0){
		dis = std::abs(S1[i] - S2[j]) + std::abs(S2[j]- S3[k]) + std::abs(S3[k] - S1[i]);
		if(dis < minLength){
			 minLength = dis;
			 res[0] = S1[i];
			 res[1] = S2[j];
			 res[2] = S3[k];
		}
		if(xIsMin(S1[i],S2[j],S3[k])) i++;
		else if(xIsMin(S2[j],S3[k],S1[i])) j++;
		else k++;
	}
	
	for(auto i:res){
		std::cout<<i<<std::endl;
	}
	
	printf("MinLength is %d", minLength);		
	
	return 0;
}

时间复杂度:O(extent1+ extent2+ extent3)

已标记关键词 清除标记
©️2020 CSDN 皮肤主题: 岁月 设计师:pinMode 返回首页