15145641

A题大意,不得不说当时后台数据多水(被人hack)。

从大到小遍历,不断累加上面的值,如果值变小了,就退出。

#include<iostream>
#include<cstdio>
#include<cstring>
#include<map>
#include<algorithm>
using namespace std;
const int N = 30;
#define LL long long
struct ZF {
    int a,s;
} zf[N];
bool cmp(ZF A,ZF B) {
    return A.a > B.a;
}
int main() {
    int T,n,x,y;
    scanf("%d",&T);
    while(T--) {
        scanf("%d",&n);
        for(int i=0; i<n; i++) {
            scanf("%d%d",&x,&y);
            zf[i].a = x;
            zf[i].s = y;
        }
        sort(zf,zf+n,cmp);
        LL Max = 0,k=1,tmp,sum=0,cnt=0;
        for(int i=0; i<n; i++) {
            for(int j=0; j<zf[i].s; j++) {
                sum += cnt+zf[i].a;
                cnt += zf[i].a;
//                printf("sum = %lld\n",sum);
                if(sum > Max) {
                    Max=sum;
                }
            }
        }
        printf("%I64d\n",Max);
    }
    return 0;
}
View Code

B题做出来没时间了,但是当时用了map,导致后来第一次交也超时,去掉后1800MS多AC,离散化1200MS多AC

这种枚举+二分的做法

#include<iostream>
#include<cstdio>
#include<cstring>
#include<map>
#include<algorithm>
using namespace std;
#define LL long long
const int N = 50005;
int d[4*N],n;
struct Edge {
    int l,r;
    LL a,b,c;
    void Set(int ll,int rr,LL aa,LL bb,LL cc) {
        l = ll;
        r = rr;
        a = aa;
        b = bb;
        c = cc;
    }
};
Edge ls[N],rs[N];
LL sumla[N],sumlb[N],sumlc[N];
LL sumra[N],sumrb[N],sumrc[N];
bool cmp1(Edge A,Edge B) {
    return A.l < B.l;
}
bool cmp2(Edge A,Edge B) {
    return A.r < B.r;
}
void getSumLR() {
    sort(ls+1,ls+n+1,cmp1);
    sumla[0] = sumlb[0] = sumlc[0] = 0;
    for(int i=1; i <= n; i++) {
        sumla[i] = sumla[i-1]+ls[i].a;
        sumlb[i] = sumlb[i-1]+ls[i].b;
        sumlc[i] = sumlc[i-1]+ls[i].c;
    }
    sort(rs+1,rs+n+1,cmp2);
    sumra[0] = sumrb[0] = sumra[0] = 0;
    for(int i=1; i <= n; i++) {
        sumra[i] = sumra[i-1]+rs[i].a;
        sumrb[i] = sumrb[i-1]+rs[i].b;
        sumrc[i] = sumrc[i-1]+rs[i].c;
    }
}
LL getAns(double x) {
    int l=1,r=n,mid,EndL=-1;
    while(l <= r) {
        mid = (l+r)>>1;
        if(ls[mid].l > x) {
            EndL = mid;
            r = mid-1;
        } else {
            l = mid+1;
        }
    }
    LL res = sumla[n];
    if(EndL != -1) {
        res -= sumla[n]-sumla[EndL-1];
        res += sumlc[n]-sumlc[EndL-1];
    }
    l=1;
    r=n;
    int EndR=-1;
    while(l <= r) {
        mid = (l+r)>>1;
        if(rs[mid].r < x) {
            l = mid+1;
            EndR = mid;
        } else {
            r = mid-1;
        }
    }
    if(EndR != -1) {
        res -= sumra[EndR];
        res += sumrb[EndR];
    }
    return res;
}
int main() {
//    freopen("in.cpp","r",stdin);
    int T,l,r,cnt;
    LL a,b,c,ans;
    scanf("%d",&T);
    while(T--) {
        cnt=1;
        scanf("%d",&n);
        d[0] = 0;
        for(int i=1; i<=n; i++) {
            scanf("%d %d %I64d %I64d %I64d",&l,&r,&a,&b,&c);
            ls[i].Set(l,r,a,b,c);
            rs[i].Set(l,r,a,b,c);
            d[cnt++] = l;
            d[cnt++] = r;
        }
        getSumLR();
        ans = 0;
        for(int i=0; i<cnt; i++) {
            ans = max(ans,getAns(d[i]));
            ans = max(ans,getAns(d[i]+0.5));
        }
        printf("%I64d\n",ans);
    }
    return 0;
}
View Code

比离散化的方法是要蠢很多的。

但是有个地方需要注意,遍历答案的时候,相同的温度需要一起加上,当时忘了。

#include<iostream>
#include<cstdio>
#include<cstring>
#include<map>
#include<algorithm>
using namespace std;
#define LL long long
const int N = 50005*3;
struct Array {
    LL val,tim;
}a[N];
bool cmp(Array A,Array B) {
    return A.tim < B.tim;
}
int main() {
//    freopen("in.cpp","r",stdin);
    int T,cnt,n;
    LL l,r,aa,b,c,ans,sum;
    scanf("%d",&T);
    while(T--) {
        cnt = sum = 0;
        scanf("%d",&n);
        for(int i=1; i<=n; i++) {
            scanf("%I64d %I64d %I64d %I64d %I64d",&l,&r,&aa,&b,&c);
            a[cnt].val = -c+aa;
            a[cnt++].tim = 2*l;
            a[cnt].val = -aa+b;
            a[cnt++].tim = 2*r+1;
            sum += c;
        }
        sort(a,a+cnt,cmp);
        ans = sum;
        for(int i=0; i<cnt; i++) {
            for(int j=i; j<cnt; j++) {
                if(a[i].tim == a[j].tim) sum += a[j].val;
                else {
                    i = j-1;
                    break;
                }
            }
            ans = max(ans,sum);
        }
        printf("%I64d\n",ans);
    }
    return 0;
}
View Code

 

posted on 2017-01-25 00:01  icode-xiaohu  阅读(193)  评论(0编辑  收藏  举报