日常训练补题

Gdufe每周练习_20171029

B - Hacker, pack your bags!

 CodeForces - 822C
这是一道贪心题,在多个区间中寻找符合要求的最小值。这种题区间题一般要固定区间让他们排序,然后按照需要遍历寻找。
这里要分两次排序,一次按照出发时间排序,一次按照返回时间排序,然后以出发时间为基础,遍历小于出发时间的返回时间的点,然后更新所需要的时间差的花费的最小值;
#include <stdio.h>
#include <stdlib.h>
#include <algorithm>
#include <string.h>

#define mx_int   2*100000+10
#define INT_MAX   2e9+10//这里设置的极大值要大于两次成本之和,所以得大于2*1e9

struct vv{
    int s,r,c;
}vv1[mx_int],vv2[mx_int];
long long min[mx_int];


bool cmp1(vv a,vv b){
    return a.s < b.s;
}
bool cmp2(vv a,vv b){
    return a.r < b.r;
}
long long getmin(long long a,long long b){
    if(a==0||b==0){
        return a > b? a:b;
    }
    return a < b ? a:b;
}
int main(){
    int n,x;
    while(~scanf("%d%d",&n,&x)){
        memset(min,0,sizeof(min));
        for(int i=0; i<n; i++){
            scanf("%d%d%d",&vv1[i].s,&vv1[i].r,&vv1[i].c);
            vv2[i] = vv1[i];
        }
        std::sort(vv1,vv1+n,cmp1);
        std::sort(vv2,vv2+n,cmp2);
        long long minn = INT_MAX;
        int j =0;
        for(int i=0; i<n; i++){
            while(j<n&&vv2[j].r<vv1[i].s){
                min[vv2[j].r - vv2[j].s + 1 ] = getmin(min[vv2[j].r - vv2[j].s + 1 ],vv2[j].c);
                j++;
            }
            int k = x - (vv1[i].r - vv1[i].s +1 );
            if(k>0&&minn > min[k] + vv1[i].c && min[k]){//更新答案,之前的区间差最小值加上当前花费。

                minn = min[k] + vv1[i].c;
            }
        }
        if(minn == INT_MAX)
            printf("-1\n");
        else
            printf("%lld\n",minn);

    }

    return 0;
}

  


 

posted @ 2017-11-18 23:21  冬瓜虾米  阅读(122)  评论(0)    收藏  举报