记Bstar复赛

靠跌成狗了==
第三题我依着良心挖了5次==
KyleYoung开黑直接卡黄了==
而我,掉回蓝民。

讲一下题目。
只A了第三题。

拍照
Description
小明在旅游的路上看到了一条美丽的河,河上有许多船只,有的船只向左航行,有的船只向右航行。小明希望拍下这一美丽的风景,并且把尽可能多的船只都完整地拍到一张照片中。

小明位于河的边上,并且可以在河边的任意位置进行拍照,照相机的视野恰好为90度角,只能以垂直于河边的方向进行拍照。河上的船只全都可看作是平行于河边的一条线段,跟河边的距离各不相同,有的正在向左移动,有的正在向右移动,但移动速度恰好都是一样的。小明可以等待恰当的时间让尽量多的船只都走进照相机的视野里,你不需要考虑船只之间会互相遮挡视野的情况。
这里写图片描述

Solution
这题蛮神==
首先把想两边开的分开
记录每个:
视野1可以看到的向左边开的
视野2可以看到的向右边开的
然后有时候视野1和视野2会重合。
记录一个最大值就好了
暴力判会T,而且内存扛不住。
所以离散一发。

#include<iostream>
#include<string.h>
#include<algorithm>
#include<stdio.h>
#include<vector>
#include<queue>
using namespace std;
const int M=2e4+5e3;
struct node{int x,y;}S[2][M];
int _,txt,cnt[2],sum[M],res[2][M],B[M];
int pos[2][M];
inline void Max(int &a,int b){if(a<b)a=b;}
inline void Min(int &a,int b){if(a>b)a=b;}
inline void gao(){
    int n;cin>>n;
    memset(sum,0,sizeof(sum));
    memset(res,0,sizeof(res));
    memset(pos,0,sizeof(pos));
    cnt[0]=cnt[1]=0;
    //Init
    int t=0;
    for(int i=1,x,y,z,d;i<=n;++i){
        scanf("%d %d %d %d",&x,&y,&z,&d);
        if(y-x>z<<1)continue;
        if(d==-1)S[1][cnt[1]++]=(node){x+z,y-z};
        else S[0][cnt[0]++]=(node){x+z,y-z};
        B[t++]=x+z,B[t++]=y-z;
    }
    //要找的是x-z=>i&&r-z<=i的 
    sort(B,B+t);
    int s=unique(B,B+t)-B;
    for(int i=0;i<cnt[0];++i){
        S[0][i].x=lower_bound(B,B+s,S[0][i].x)-B;
        S[0][i].y=lower_bound(B,B+s,S[0][i].y)-B;
    }
    for(int i=0;i<cnt[1];++i){
        S[1][i].x=lower_bound(B,B+s,S[1][i].x)-B;
        S[1][i].y=lower_bound(B,B+s,S[1][i].y)-B;
    }
    for(int i=0;i<cnt[0];++i)
        pos[0][S[0][i].y]++,pos[0][S[0][i].x+1]--;
    for(int i=0;i<cnt[1];++i)
        pos[1][S[1][i].y]++,pos[1][S[1][i].x+1]--;
    int sum1=0,sum2=0;
    for(int i=0;i<s;++i){
        sum1+=pos[0][i];
        res[0][i]=sum1;
        sum2+=pos[1][i];
        res[1][i]=sum2;
    }
    sum[0]=res[0][0];
    for(int i=1;i<s;++i)
        sum[i]=max(sum[i-1],res[0][i]);
    int ans=0;sum1=0;
    for(int i=s-1;~i;--i){
        Max(sum1,res[1][i]);
        Max(ans,sum[i]+sum1);
    }    
    printf("Case #%d:\n",++txt);
    printf("%d\n",ans);
}
int main(){
    for(cin>>_;_--;)gao();
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值