【408计算机考研】|【2020统考真题-41】| 定义三元组(a, b, c)的距离D=|a-b| + |b-c| + |c-a|,计算给定3个非空整数集合S1, S2和S3中所有可能的最小距离

一、题目

  定义三元组(a, b, c)(其中a, b, c均为正数)的距离D=|a-b| + |b-c| + |c-a|。给定三个非空整数集合S1、S2和S3,按升序分别存储在3个数组中。设计一个尽可能高效的算法,计算并输出所有可能的三元组(a, b, c)(a∈S1, b∈S2, c∈S3)中的最小距离。要求:
 (1)给出算法的基本设计思想。
 (2)根据设计思想,采用 C 或 C++语言描述算法,关键之处给出注释。
 (3)说明你所设计算法的时间复杂度和空间复杂度。

二、解答

(1)通过三个队列每次出队最小值的策略;
(2)C++实现:

// -*- coding: utf-8 -*-
//  @ Date   : 2021/5/20 13:14
//  @ Author : RichardLau_Cx
//  @ file   : Richard.cpp
//  @ IDE    : Dev-C++
//  @ Source : Data_Structure

#include <iostream>
#include <cstdlib> 
#include <queue>

using namespace std; 

int minimum(int a, int b, int c)
{  // 返回三个值中最小的那个值 
	if (a <= b && a <= c) 
	{		
		return a;
	} 
	
	else if (b <= a && b <= c) 
	{
		return b;
	} 
	
	else if (c <= a && c <= b) 
	{
		return c;	
	}
	
	else return 0;
}

int func(queue<int> que1, queue<int> que2, queue<int> que3)
{   /** 核心功能算法部分 
	 * *quei: 分别传入三个不同的队列元素,分别对于题目中的a, b, c 
	 */
	// 获取元素个数
	int len1, len2, len3;
	len1 = que1.size();   
	len2 = que2.size();  
	len3 = que3.size();  
	
//	cout << que1.size() << que2.size() << que3.size() << endl;  // 查看队列长度(元素个数) 
	
	/*
	for (int i=0; i < len1; i++)
	{  // 队列查看
		cout << que1.front() << ' ';  // 返回队首元素的值,但不删除该元素 
		que1.pop();  // 删除队列首元素但不返回其值 
	}
	*/
	
	int min = 99;  // 初始化最小值 
	int temp;  // 中间临时值 
	int q1, q2, q3;  // 为了表示简洁,对每轮元素名进行替换 
	
	while(que1.size() != 0 && que2.size() != 0 && que3.size() != 0)
	{
		q1 = que1.front();
		q2 = que2.front();
		q3 = que3.front();
		
		temp = abs(q1 - q2) + abs(q2 - q3) + abs(q3 - q1);
		
		/* 
		// 由于switch 语句中的 expression 是一个常量表达式,必须是一个整型或枚举类型。所以改用if-else语句 
		switch(minimum(q1, q2, q3))
		{
			case q1: que1.pop(); break;
			case q2: que2.pop(); break;
			case q3: que3.pop(); break;
		}
		*/
		
		if(minimum(q1, q2, q3) == q1) que1.pop();
		else if (minimum(q1, q2, q3) == q2) que2.pop();
		else if (minimum(q1, q2, q3) == q3) que3.pop();
		else return 0;
		
		if(temp < min)
		{
			min = temp;
		 } 
	 } 
	
	return min;
}

int main()
{
	// 定义三个非空整数集
	int set1[] = {-1, 0, 9};
	int set2[] = {-25, -10, 10, 11};
	int set3[] = {2, 9, 17, 30, 41};
	
	/* (也可采用循环赋值) 
	for (int i=0; i < n; i++)
	{
		cin >> set1[i];
	 } 
	*/
	
	// 获取集合元素个数
	int len1, len2, len3;
	len1 = sizeof(set1) / sizeof(int);   
	len2 = sizeof(set2) / sizeof(int);  
	len3 = sizeof(set3) / sizeof(int);  
	
//	cout << len1 << len2 << len3 << endl;  // 查看集合长度(元素个数) 
	
	/*
	for (int i=0; i < len1; i++)
	{  // 集合数据测试 
		cout << set1[i] << ' ';
	 } 
	*/
	
	// 定义三个队列 
	queue<int> que1, que2, que3;
	
	// 将三个集合入三个队列 
	for (int i=0; i < len1; i++)
	{
		que1.push(set1[i]);
	}
	
	for (int i=0; i < len2; i++)
	{
		que2.push(set2[i]);
	}
	
	for (int i=0; i < len3; i++)
	{
		que3.push(set3[i]);
	}
	
	/* 
	for (int i=0; i < len2; i++)
	{  // 队列查看 
		cout << que2.front() << ' ';  // 返回队首元素的值,但不删除该元素 
		que2.pop();  // 删除队列首元素但不返回其值 
	}
	*/ 
	
	cout << "三元组两两最小间距和为:" << func(que1, que2, que3);
	
	return 0;
 } 

(3)时空复杂度(针对核心功能算法而言):

  • 时间复杂度:一个for循环,T(n) = O(n);
  • 空间复杂度:辅助空间均为离散常量(不包括队列),S(n) = O(1)。

三、测试数据

// 定义三个非空整数集
	int set1[] = {-1, 0, 9};
	int set2[] = {-25, -10, 10, 11};
	int set3[] = {2, 9, 17, 30, 41};

在这里插入图片描述

  • 7
    点赞
  • 13
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值