1. 程式人生 > >hihoCoder #1514 : 偶像的條件(模擬、二分)

hihoCoder #1514 : 偶像的條件(模擬、二分)

#1514 : 偶像的條件

時間限制:10000ms 單點時限:1000ms 記憶體限制:256MB

描述

小Hi的學校正面臨著廢校的大危機。面對學校的危機,小Hi同學們決定從ABC三個班中各挑出一名同學成為偶像。  

成為偶像團體的條件之一,就是3名團員之間的身高差越小越好。  

已知ABC三個班同學的身高分別是A1..AN, B1..BM 和 C1..CL。請你從中選出3名同學Ai, Bj, Ck使得D=|Ai-Bj|+|Bj-Ck|+|Ck-Ai|最小。

輸入

第一行包含3個整數,N, M和L。  

第二行包含N個整數,A1, A2, ... AN。(1 <= Ai <= 100000000)

第三行包含M個整數,B1, B2, ... BM。(1 <= Bi <= 100000000)

第四行包含L個整數,C1, C2, ... CL。(1 <= Ci <= 100000000)

對於30%的資料, 1 <= N, M, L <= 100  

對於60%的資料,1 <= N, M, L <= 1000  

對於100%的資料,1 <= N, M, L <= 100000

輸出

輸出最小的D。

樣例輸入
3 3 3  
170 180 190  
195 185 175  
180 160 200
樣例輸出
10

解析:資料10^5比較大,暴力會超時,咱可以列舉ABC班中任意一個班,其他班用二分查詢,一直維護最小值即可,輸入比較大,這裡用到了輸入掛

程式碼:

#include<bits/stdc++.h>
#define N 100009
using namespace std;
const int INF = 0x3f3f3f3f;
int a[N], b[N], c[N];

inline void q_read(int &num)
{
    char ch; int f = 1;
    while(true)
    {
        ch = getchar();
        if(ch == '-') f = -1;
        if(isdigit(ch))
        {
            num = ch - '0';
            break;
        }
    }
    while(ch = getchar(), isdigit(ch)) num = num*10+ch-'0';
    num *= f;
}

int main()
{
    int n, m, l;
    q_read(n); q_read(m); q_read(l);
    for(int i = 0; i < n; i++) q_read(a[i]);
    for(int i = 0; i < m; i++) q_read(b[i]);
    for(int i = 0; i < l; i++) q_read(c[i]);
    sort(b, b + m);
    sort(c, c + l);
    int ans = INF, bb, cc;
    for(int i = 0; i < n; i++)
    {
        int j = lower_bound(b, b + m, a[i]) - b;
        bb = abs(a[i]-b[j]) > abs(a[i]-b[j-1]) ? b[j-1] : b[j];
        int k = lower_bound(c, c + l, a[i]) - c;
        cc = abs(a[i]-c[k]) > abs(a[i]-c[k-1]) ? c[k-1] : c[k];
        ans = min(ans, abs(a[i]-bb)+abs(a[i]-cc)+abs(bb-cc));

    }
    printf("%d\n", ans);
    return 0;
}