三元组的离心力c++

题目描述

三元组(a,b,c) 的“离心力”定义为 |a-b|+|b-c|+|c-al。现给定三个非空的整数集合S1、S2、S3,请你找出所有跨这三个集合的三元组(a,b,c)(即 aE Sy, bE S2,CE S3)的最小离心力。

时间限制:1000

内存限制:65536输入

输入描述
输入第一行给出三个不超过104 的正整数n1、n2、n3,依次为集合 S1、S2、S₃中元素的个数(注意一个集合内没有相同的元素)。随后三行,顺次给出三个集合的元素,均为[-104,104]内的整数。同行数字间以空格分隔。

输出描述
在一行中输出LiXinLi(a,b,c)= d`,其中`(a,b,c)’是具有最小离心力的三元组,d是对应的离心力。如果解不唯一,输出那个最大的解。注意:(a1,a2,aз)>(b1,b2,b3) 是指,存在1≤k≤3 使得a=bi对1≤i<k成立,并且ax>bko

输入样例

4 4 6
0 9 -1 11
10 -25 11 -10
9 2 41 17 12 30

输出样例

LiXinLi(11, 11, 12) = 2

参考代码

#include <iostream>
#include <vector>
#include <tuple>
#include <algorithm>
#include <climits>

using namespace std;

vector<int> find_closest(const vector<int>& arr, int x) {
	vector<int> res;
	int n = arr.size();
	if (n == 0) return res;
	auto it = lower_bound(arr.begin(), arr.end(), x);
	int pos = it - arr.begin();
	if (pos == 0) {
		res.push_back(arr[0]);
	} else if (pos == n) {
		res.push_back(arr.back());
	} else {
		int prev = arr[pos - 1];
		int curr = arr[pos];
		if (x - prev < curr - x) {
			res.push_back(prev);
		} else if (x - prev > curr - x) {
			res.push_back(curr);
		} else {
			res.push_back(prev);
			res.push_back(curr);
		}
	}
	return res;
}

int main() {
	int n1, n2, n3;
	cin >> n1 >> n2 >> n3;
	vector<int> S1(n1), S2(n2), S3(n3);
	for (int i = 0; i < n1; ++i) cin >> S1[i];
	for (int i = 0; i < n2; ++i) cin >> S2[i];
	for (int i = 0; i < n3; ++i) cin >> S3[i];
	
	sort(S1.begin(), S1.end());
	sort(S2.begin(), S2.end());
	sort(S3.begin(), S3.end());
	
	vector<tuple<int, int, int>> candidates;
	
	// Process S1 elements
	for (int a : S1) {
		auto b_list = find_closest(S2, a);
		auto c_list = find_closest(S3, a);
		for (int b : b_list) {
			for (int c : c_list) {
				candidates.emplace_back(a, b, c);
			}
		}
	}
	
	// Process S2 elements
	for (int b : S2) {
		auto a_list = find_closest(S1, b);
		auto c_list = find_closest(S3, b);
		for (int a : a_list) {
			for (int c : c_list) {
				candidates.emplace_back(a, b, c);
			}
		}
	}
	
	// Process S3 elements
	for (int c : S3) {
		auto a_list = find_closest(S1, c);
		auto b_list = find_closest(S2, c);
		for (int a : a_list) {
			for (int b : b_list) {
				candidates.emplace_back(a, b, c);
			}
		}
	}
	
	int min_range = INT_MAX;
	for (const auto& t : candidates) {
		int a = get<0>(t), b = get<1>(t), c = get<2>(t);
		int current_min = min({a, b, c});
		int current_max = max({a, b, c});
		min_range = min(min_range, current_max - current_min);
	}
	
	vector<tuple<int, int, int>> min_candidates;
	for (const auto& t : candidates) {
		int a = get<0>(t), b = get<1>(t), c = get<2>(t);
		int current_min = min({a, b, c});
		int current_max = max({a, b, c});
		if (current_max - current_min == min_range) {
			min_candidates.push_back(t);
		}
	}
	
	tuple<int, int, int> best = min_candidates[0];
	for (const auto& t : min_candidates) {
		if (t > best) {
			best = t;
		}
	}
	
	int a = get<0>(best), b = get<1>(best), c = get<2>(best);
	int d = 2 * (max({a, b, c}) - min({a, b, c}));
	cout << "LiXinLi(" << a << ", " << b << ", " << c << ") = " << d << endl;
	
	return 0;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值