【[Offer收割]编程练习赛15 A】 偶像的条件

【题目链接】:http://hihocoder.com/contest/offers15/problem/1

【题意】

【题解】

把3个数组的元素全都合并在一个数组里面;
(当然你要记录每个数字原本是在哪一个数组里面的)
然后排个序;
找到原本a,b,c数组中的元素第一次出现的位置
pos[1],pos[2],pos[3];
然后按照公式直接计算
D=?
然后把,pos[1],pos[2],pos[3]中最小的那个pos[i]
令pos[i]=nex(pos[i]);
然后再重新计算D=?
重复上述步骤取最小的D就好;
贪心吧
相邻的肯定差最小;
看看是哪3个构成了最后的答案而已;

【Number Of WA

0

【完整代码】

#include <bits/stdc++.h>
using namespace std;
#define lson l,m,rt<<1
#define rson m+1,r,rt<<1|1
#define LL long long
#define rep1(i,a,b) for (int i = a;i <= b;i++)
#define rep2(i,a,b) for (int i = a;i >= b;i--)
#define mp make_pair
#define pb push_back
#define fi first
#define se second
#define ms(x,y) memset(x,y,sizeof x)

typedef pair<int,int> pii;
typedef pair<LL,LL> pll;

const int dx[9] = {0,1,-1,0,0,-1,-1,1,1};
const int dy[9] = {0,0,0,-1,1,-1,1,-1,1};
const double pi = acos(-1.0);
const LL MOD = 1e9+7;
const int N = 3*(1e5+100);

struct abc
{
    int id,val;
};

int n,m,l,cnt,pos[4],ans;
abc a[N];

bool cmp1(abc a,abc b)
{
    return a.val < b.val;
}

int nex(int x)
{
    int r = pos[x];
    pos[x] = n+1;
    rep1(i,r+1,n)
        if (a[i].id==x)
        {
            pos[x] = i;
            break;
        }
    return pos[x];
}

int fi()
{
    int ju = 1;
    if (pos[2]<pos[ju]) ju = 2;
    if (pos[3]<pos[ju]) ju = 3;
    return ju;
}

int getd()
{
    return abs(a[pos[1]].val-a[pos[2]].val)+
    abs(a[pos[2]].val-a[pos[3]].val)+
    abs(a[pos[3]].val-a[pos[1]].val);
}

int main()
{
    //freopen("F:\\rush.txt","r",stdin);
    cin >> n >> m >> l;
    rep1(i,1,n) cin >> a[++cnt].val,a[cnt].id = 1;
    rep1(i,1,m) cin >> a[++cnt].val,a[cnt].id = 2;
    rep1(i,1,l) cin >> a[++cnt].val,a[cnt].id = 3;
    n = cnt;
    sort(a+1,a+1+n,cmp1);
    rep1(i,1,3) pos[i] = nex(i);
    ans = getd();
    while (1)
    {
        int mi = fi();
        pos[mi] = nex(mi);
        if (pos[mi]==n+1) break;
        ans = min(ans,getd());
    }
    cout << ans << endl;
    return 0;
}
posted @ 2017-10-04 18:44  AWCXV  阅读(140)  评论(0编辑  收藏  举报