• ZOJ-3597-Hit the Target!(线段树+扫描线)


    题解引自:http://www.cnblogs.com/wuyiqi/archive/2012/04/28/2474614.html

    这题和着题解一块看,看了半天才看懂的....菜菜....

    题意:有一排的枪编号依次为1~n 有一排靶子编号依次为1~m

    告诉你哪些枪能打中哪些靶子,然后如果每次只能选连续的P把枪,连续的Q个靶子,每次能打中的靶子的最大值为多少

    答案是把每次打中的最大值相加再除以总的次数

    即选择 1~P 的枪能打中的最多的靶子的数量 + 2~p+1 的枪能打中的最多的靶子的数量 +。。。n-p+1~n的枪能打中的最多的靶子的数量 /(n-p+1)

    注意,每把枪最多只能打一个靶子

    解法:将题目中的关系转换为坐标 以枪为纵坐标 a 能打中 b ,在坐标系中为(b,a),然后连续的P把枪和连续的Q个靶子则可以表示为

    用一个P x Q的矩形去覆盖,最多能覆盖的总的点数,就是poj 2482 了,但要注意一点,如果两根同一高度的水平线的距离小于Q,则重叠的部分职能算一次,因为每把枪只能打一个靶子

    // File Name: 3597.cpp
    // Author: Zlbing
    // Created Time: 2013/7/21 14:25:06
    
    #include<iostream>
    #include<string>
    #include<algorithm>
    #include<cstdlib>
    #include<cstdio>
    #include<set>
    #include<map>
    #include<vector>
    #include<cstring>
    #include<stack>
    #include<cmath>
    #include<queue>
    using namespace std;
    #define CL(x,v); memset(x,v,sizeof(x));
    #define INF 0x3f3f3f3f
    #define LL long long
    #define REP(i,r,n) for(int i=r;i<=n;i++)
    #define RREP(i,n,r) for(int i=n;i>=r;i--)
    
    #define lson l,m,rt<<1
    #define rson m+1,r,rt<<1|1
    
    const int MAXN=5e4+100;
    struct point{
        int x,y;
        bool operator <(const point& rsh)const{
            if(y==rsh.y)return x<rsh.x;
            else return y<rsh.y;
        }
    }G[100050];
    
    int sum[MAXN<<2];
    int col[MAXN<<2];
    
    void pushup(int rt)
    {
        sum[rt]=max(sum[rt<<1],sum[rt<<1|1]);
    }
    void pushdown(int rt)
    {
        if(col[rt])
        {
            sum[rt<<1]+=col[rt];
            sum[rt<<1|1]+=col[rt];
            col[rt<<1]+=col[rt];
            col[rt<<1|1]+=col[rt];
            col[rt]=0;
        }
    }
    void update(int L,int R,int flag,int l,int r,int rt)
    {
        if(L<=l&&R>=r)
        {
            col[rt]+=flag;
            sum[rt]+=flag;
            return;
        }
        pushdown(rt);
        int m=(l+r)>>1;
        if(L<=m)update(L,R,flag,lson);
        if(R>m)update(L,R,flag,rson);
        pushup(rt);
    }
    int main()
    {
        int T;
        scanf("%d",&T);
        while(T--)
        {
            int n,m,p,q,K;
            scanf("%d%d%d%d",&n,&m,&p,&q);
            scanf("%d",&K);
            for(int i=0;i<K;i++)
            {
                scanf("%d%d",&G[i].y,&G[i].x);
            }
            sort(G,G+K);
            int ans=0;
            int j=0,k=0;
            CL(sum,0);
            CL(col,0);
            for(int i=1;i+p-1<=n;i++)
            {
                
                for(;G[j].y-i<p&&j<K;j++)
                {
                    if(j+1<K&&G[j].y==G[j+1].y&&G[j+1].x-G[j].x<q)
                        update(G[j].x,G[j+1].x-1,1,1,m,1);
                    else
                        update(G[j].x,min(m,G[j].x+q-1),1,1,m,1);
                }
                ans+=sum[1];
                for(;k<j&&G[k].y==i;k++)
                {
                    if(k+1<j&&G[k].y==G[k+1].y&&G[k+1].x-G[k].x<q)
                        update(G[k].x,G[k+1].x-1,-1,1,m,1);
                    else 
                        update(G[k].x,min(m,G[k].x+q-1),-1,1,m,1);
                }
            }
            printf("%.2lf
    ",(double)ans/(n-p+1));
        }
        return 0;
    }
  • 相关阅读:
    VMWare安装Win10虚拟机 昆明
    c#游戏进程杀手 昆明
    图解机器学习读书笔记CH2
    深度学习中的线性代数知识详解
    图解机器学习读书笔记CH1
    三分算法
    POJ 2356 Find a multiple【抽屉原理】
    POJ 1170 Shoping Offers(IOI 95)
    HDU 2438 Turn the corner【三分】
    HDU 3552 I can do it! 【贪心】
  • 原文地址:https://www.cnblogs.com/arbitrary/p/3203785.html
Copyright © 2020-2023  润新知