zoukankan      html  css  js  c++  java
  • 『妙不可言系列1』CF635D:Xenia and Colorful Gems

    (mathrm{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) red gems, (n_g) green gems and (n_b) 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) , (y) and (z) , Xenia wants to find the minimum value of ((x-y)^2+(y-z)^2+(z-x)^2) . As her dear friend, can you help her?

    给定三个正整数数列 (r,g,b),长度分别为 (n_r,n_g,n_b)

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

    多组测试数据(1 leq r_i,g_i,b_i leq 10^9)(1 leq n_r,n_g,n_b leq 10^5)(1 leq sum n_r, sum n_g,sum n_b leq 10^5)

    (mathrm{Solution})

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

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

    [xle yle z\xle zle y\yle xle z\yle zle x\zle xle y\ zle yle x ]

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

    (mathrm{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
    ", res); 
    }
     
    signed main(void)
    {
    	int T = read();
    	while (T --) work();
    	return 0;
    }
    

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

  • 相关阅读:
    算法笔记_035:寻找最小的k个数(Java)
    (中级篇 NettyNIO编解码开发)第六章-编解码技术
    (入门篇 NettyNIO开发指南)第五章-分隔符和定长解码器使用
    (入门篇 NettyNIO开发指南)第四章-TIP黏包/拆包问题解决之道
    (入门篇 NettyNIO开发指南)第三章-Netty入门应用
    (基础篇 走进javaNIO)第二章-NIO入门
    (基础篇 走进javaNIO)第一章-java的i/o演进之路
    Apache Commons 工具类介绍及简单使用
    SimpleDateFormat使用和线程安全问题
    Calendar使用
  • 原文地址:https://www.cnblogs.com/pigzhouyb/p/12755387.html
Copyright © 2011-2022 走看看