zoukankan      html  css  js  c++  java
  • NOIP模拟赛 最佳组合

    题目描述 Description###

    (Bzeroth) 大陆最终还是覆灭了,所以你需要为地灾军团服务了。
    地灾军团军师黑袍不擅长写题面,所以你只需要看简化版的题意即可。
    给定 (3) 个长度均为 (N) 的正整数序列 (A)(B)(C) ,要求从三个序列中分别取出 (3) 个数 (A_i)(B_j)(C_k) ,使得 (| C_k - B_j | + | C_k - A_i | + | B_j - A_i |) 最小。

    输入描述 Input Description###

    第一行一个正整数 (N)
    第二行 (N) 个正整数,第 i 个数为 (A_i)
    第三行 (N) 个正整数,第 i 个数为 (B_i)
    第四行 (N) 个正整数,第 i 个数为 (C_i)

    输出描述 Output Description###

    输出(| C_k - B_j | + | C_k - A_i | + | B_j - A_i |) 的最小值。

    样例输入 Sample Input###

    3
    170 180 190
    195 185 175
    180 160 200
    

    样例输出 Sample Output###

    10
    

    数据范围及提示 Data Size & Hint###

    $ n leq 152501 $

    之前的一些废话###

    题解###

    先对(A,B,C) 数组排序,然后枚举(A) 中的元素,很显然当(B,C) 数组中的数与(A_i) 相差最小时答案最小,所以我们二分出(B) ,(C) 数组中(A_i) 的位置,然后算一算更新答案即可。

    代码###

    #include<iostream>
    #include<cmath>
    #include<algorithm>
    #include<cstdio>
    #include<cstring>
    #include<queue>
    using namespace std;
    typedef long long LL;
    typedef pair<int,int> PII;
    #define mem(a,b) memset(a,b,sizeof(a))
    inline int read()
    {
    	int x=0,f=1;char c=getchar();
    	while(!isdigit(c)){if(c=='-')f=-1;c=getchar();}
    	while(isdigit(c)){x=x*10+c-'0';c=getchar();}
    	return x*f;
    }
    const int maxn=152510,oo=2147483647;
    int n,A[maxn],B[maxn],C[maxn];
    LL ans=oo;
    bool judge(int k){return k>=0 && k<n;}
    int main()
    {
    	n=read();
    	for(int i=0;i<n;i++)A[i]=read();
    	for(int i=0;i<n;i++)B[i]=read();
    	for(int i=0;i<n;i++)C[i]=read();
    	sort(A,A+n);sort(B,B+n);sort(C,C+n);
    	for(int i=0;i<n;i++)
    	{
    		int Br=lower_bound(B,B+n,A[i])-B,Bl=-1;
    		if(Br>0)Bl=Br-1;
    		int Cr=lower_bound(C,C+n,A[i])-C,Cl=-1;
    		if(Cr>0)Cl=Cr-1;
    		if(judge(Br) && judge(Cr))ans=min(ans,(LL)abs(A[i]-B[Br])+(LL)abs(A[i]-C[Cr])+(LL)abs(B[Br]-C[Cr]));
    		if(judge(Br) && judge(Cl))ans=min(ans,(LL)abs(A[i]-B[Br])+(LL)abs(A[i]-C[Cl])+(LL)abs(B[Br]-C[Cl]));
    		if(judge(Bl) && judge(Cr))ans=min(ans,(LL)abs(A[i]-B[Bl])+(LL)abs(A[i]-C[Cr])+(LL)abs(B[Bl]-C[Cr]));
    		if(judge(Bl) && judge(Cl))ans=min(ans,(LL)abs(A[i]-B[Bl])+(LL)abs(A[i]-C[Cl])+(LL)abs(B[Bl]-C[Cl]));
    	}
    	printf("%lld",ans);
    	return 0;
    }
    

    总结###

  • 相关阅读:
    MFC对话框控件数据提取之DoDataExchange()
    慎用USES_CONVERSION
    Oracle OCP 11G 051(61题版本)答案解析目录
    OCP-1Z0-新051-61题版本-61
    OCP-1Z0-新051-61题版本-60
    OCP-1Z0-新051-61题版本-59
    OCP-1Z0-新051-61题版本-58
    OCP-1Z0-新051-61题版本-57
    OCP-1Z0-新051-61题版本-55
    OCP-1Z0-新051-61题版本-56
  • 原文地址:https://www.cnblogs.com/FYH-SSGSS/p/7774727.html
Copyright © 2011-2022 走看看