hdu5714 百度之星复赛C

来源:互联网 发布:网络暴力 人肉 编辑:程序博客网 时间:2024/05/18 19:43

恩。。大概就是如果 y - z <= x +z , 那么 对于这一艘船来说,在[y - z , x +z ]这个区域都可以完整的观察到它

转换成 y - z 为左端点,x + z 为右端点,的n 条线段

把向右走的船看成固定不动的, 在这些船右边, 向左走的船在同一时刻最多有多少条

now记录当前端点处,垂直河岸的线能交叉几条(向左,向右)线段,ans[i]记录当前端点右侧,垂直河岸的线最多能交叉几条(向左)线段

sort的时候,先按位置从小到大排,再按左端点右端点排,最后按向左或向右排都无所谓啦

#include <iostream>#include<stdio.h>#include<cctype>#include<cstdlib>#include<math.h>#include<algorithm>#include<cstring>#include<string>#include<vector>#include<queue>#include<map>#include<set>#include<stack>using namespace std;#define mod 1000000007#define FOR(i,j,k) for(int i=j;i<=k;i++)const int inf=0x3f3f3f3f;const int maxn = 20010;struct node{    int x, val , op;    friend bool operator <(const node &a, const node &b)    {        if (a.x != b.x) return a.x < b.x;        if (a. val  != b.val) return a.val > b.val;        return a.op < b.op;    }    }nd[maxn];int ans[maxn];int main(){    int T;    scanf("%d" , &T);    FOR(z, 1, T)    {        int n;        scanf("%d" ,&n);        int tot = 0;        FOR(i, 1, n)        {            int x,y,z, op;            scanf("%d%d%d%d" , & x, &y, &z, & op);            if(y - z <= x +z){                tot++;                nd[tot].x= y-z, nd[tot].val = 1, nd[tot].op = op;                tot++;                nd[tot].x= x+z, nd[tot].val = -1, nd[tot].op = op;            }        }        sort(nd +1, nd+1 +tot);            memset(ans , 0,sizeof(ans));        int now =0;                for(int i = tot; i>= 1;i--)        {            if(nd[i].op == -1 && nd[i].val == -1) now ++;            ans[i] = max(ans[i+1] , now);            if(nd[i].op == -1 && nd[i].val == 1) now--;        }                now = 0;        int sum = 0;        FOR(i, 1, tot)        {            if(nd[i]. op == 1)            {                if(nd[i].val == 1 ) now ++;                sum = max(sum, now + ans[i]);                if(nd[i].val == -1) now --;            }        }        printf("Case #%d:\n%d\n",z,sum);    }}


0 0
原创粉丝点击