『妙不可言系列1』CF635D:Xenia and Colorful Gems

P r o b l e m \mathrm{Problem} Problem

Xenia is a girl being born a noble. Due to the inflexibility and harshness of her family, Xenia has to find some ways to amuse herself.

Recently Xenia has bought n r n_r nr red gems, n g n_g ng green gems and n b n_b nb blue gems. Each of the gems has a weight.

Now, she is going to pick three gems.

Xenia loves colorful things, so she will pick exactly one gem of each color.

Xenia loves balance, so she will try to pick gems with little difference in weight.

Specifically, supposing the weights of the picked gems are x x x , y y y and z z z , Xenia wants to find the minimum value of ( x − y ) 2 + ( y − z ) 2 + ( z − x ) 2 (x-y)^2+(y-z)^2+(z-x)^2 (xy)2+(yz)2+(zx)2 . As her dear friend, can you help her?

给定三个正整数数列 r , g , b r,g,b r,g,b,长度分别为 n r , n g , n b n_r,n_g,n_b nr,ng,nb

您需要在三个数列中各取一个整数 x , y , z x,y,z x,y,z,使得 ( x − y ) 2 + ( y − z ) 2 + ( z − x ) 2 (x-y)^2+(y-z)^2+(z-x)^2 (xy)2+(yz)2+(zx)2 最小。

多组测试数据 1 ≤ r i , g i , b i ≤ 1 0 9 1 \leq r_i,g_i,b_i \leq 10^9 1ri,gi,bi109 1 ≤ n r , n g , n b ≤ 1 0 5 1 \leq n_r,n_g,n_b \leq 10^5 1nr,ng,nb105 1 ≤ ∑ n r , ∑ n g , ∑ n b ≤ 1 0 5 1 \leq \sum n_r, \sum n_g,\sum n_b \leq 10^5 1nr,ng,nb105

S o l u t i o n \mathrm{Solution} Solution

显然尽量相邻可以使得相邻的数尽可能的小,那么我们通过什么手段才能将相邻的所有情况都能枚举到呢?

假设我们在三组中都找到了 x x x y y y z z z,那么一定是这6种情况之一:
x ≤ y ≤ z x ≤ z ≤ y y ≤ x ≤ z y ≤ z ≤ x z ≤ x ≤ y z ≤ y ≤ x x\le y\le z\\x\le z\le y\\y\le x\le z\\y\le z\le x\\z\le x\le y\\ z\le y\le x xyzxzyyxzyzxzxyzyx

然后就可以根据这六种情况去枚举中间那个数字,用双指针维护即可。

C o d e \mathrm{Code} Code

#include <bits/stdc++.h>
#define int long long

using namespace std;
const int N = 2e5;

int a[N], b[N], c[N];

int read(void) {
    int s = 0, w = 0;
    char c = getchar();
    while (c < '0' || c > '9') w |= c == '-', c = getchar();
    while (c >= '0' && c <= '9') s = s * 10 + c - 48, c = getchar();
    return w ? -s : s;
}

int val(int a,int b,int c) {
	return a * a + b * b + c * c; 
}

int work(int a[N],int b[N],int c[N],int A,int B,int C)
{
	int j = 1, k = 1, res = LONG_LONG_MAX;
	for (int i=1;i<=A;++i)
	{
		while (j < B && b[j+1] <= a[i]) j ++;
		while (k < C && c[k] < a[i]) k ++;
		res = min(res,val(a[i]-b[j],a[i]-c[k],b[j]-c[k])); 
	}
	return res;
}

void work(void)
{
	int A = read(), B = read(), C = read(), res = LONG_LONG_MAX;
	for (int i=1;i<=A;++i) a[i] = read();
	for (int i=1;i<=B;++i) b[i] = read();
	for (int i=1;i<=C;++i) c[i] = read();
	res = min(res,work(a,b,c,A,B,C));
	res = min(res,work(a,c,b,A,C,B));
	res = min(res,work(b,a,c,B,A,C));
	res = min(res,work(b,c,a,B,C,A));
	res = min(res,work(c,a,b,C,A,B));
	res = min(res,work(c,b,a,C,B,A));
	printf("%lld\n", res); 
}
 
signed main(void)
{
	int T = read();
	while (T --) work();
	return 0;
}

妙 啊 ( ` ・ ω ・ ´ ) 妙啊(`・ω・´) (ω´)

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值