zoukankan      html  css  js  c++  java
  • Cogs 1995. Yukari

    1995. Yukari

    ★★☆   输入文件:camera.in   输出文件:camera.out   简单对比
    时间限制:1 s   内存限制:128 MB

    题目背景:

           幻想乡的创始人之一,八云紫,有着强大的控制结界的能力,可以瞬间消除一定范围内所有弹幕。我们可以将其消除范围视为一个矩形,而弹幕可以视为动点。

           八云紫想要嘲讽她的敌人,所以她希望只使用一次消除能力,尽可能多地消除弹幕。

           请你告诉她,在哪一时刻使用道具,可以消除尽可能多的弹幕。

     

     

    问题描述:

           在平面上给定一个矩形区域(也可能退化成线段或者点)。

           矩形的边与坐标轴平行,左下端点为 (xl,yl),右上端点为 (xr,yr)。

           给定 n 个动点,初始坐标为 (xi, yi),运动方向为 (ui,vi),速度为 sqrt((ui)^2+(vi)^2)

           求在哪一时刻 t (t ∈ N),在矩形内部及边界的动点数目最多。

           如果有多个 t 满足条件,输出最小的 t 即可。

     

     

    输入格式:

           第一行 5 个正整数,n, xl, yl, xr, yr,表示动点个数和矩形区域。

           接下来 n 行,每行 4 个整数,xi, yi, ui, vi ,描述第 i 个动点。

     

     

    输出格式:

            在矩形内部及边界的动点数目最多的时刻 t (t ∈ N)。

           如果有多个 t 满足条件,输出最小的 t 即可。

     

     

     

     

    样例数据1:

    camera.in

    camera.out

    2 2 2 3 3

    3 1 -1 1

    2 3 1 -1

    1

     

    样例数据2:

    camera.in

    camera.out

    13 44 68 49 73

    40 46 2 6

    28 75 4 -1

    32 61 3 3

    41 64 2 1

    40 99 2 -7

    54 49 -2 6

    32 80 4 -2

    73 99 -7 -7

    23 93 6 -5

    44 96 0 -6

    36 70 3 0

    70 98 -6 -7

    75 53 -7 4

    4

     

     

    数据范围:

           对于前 40% 数据,

           1<= n <= 100, 1 <= xl, xr, yl, yr, xi, yi <= 100, -10 <= ui, vi <= 10

     

           对于100% 数据,

           1<= n <= 10^5, 1 <= xl, xr, yl, yr, xi, yi <= 10^9, 0 <= |ui|, |vi|<= 10^5, xl <= xr, yl <= yr

     

           保证 n,xl,xr,yl,yr,xi,yi,ui,vi 均为整数.

    #include<iostream>
    #include<cstdio>
    #include<algorithm>
    #include<cstring>
    #define maxn 1000010
    using namespace std;
    int n,xl,yl,xr,yr;
    int tot,cnt,sum[maxn],cnt1;
    double l[maxn],r[maxn],h[maxn*2],h1[maxn*2];
    int find(int x){
        int l=1,r=cnt,res=0;
        while(l<=r){
            int mid=(l+r)>>1;
            if(h[mid]<=x)res=mid,l=mid+1;
            else r=mid-1;
        }
        return res;
    }
    int main(){
        //freopen("camera.in","r",stdin);freopen("camera.out","w",stdout);
        freopen("Cola.txt","r",stdin);
        scanf("%d%d%d%d%d",&n,&xl,&yl,&xr,&yr);
        int x,y,u,v;
        int t1,t2,sx1,sx2,sy1,sy2;
        memset(r,127,sizeof(r));
        for(int i=1;i<=n;i++){
            scanf("%d%d%d%d",&x,&y,&u,&v);
            if((x<xl&&u<=0)||(x>xr&&u>=0)||(y<yl&&v<=0)||(y>yr&&v>=0))continue;
            tot++;
            if(x<=xr&&x>=xl&&y<=yr&&y>=yl){
                l[tot]=0;
                if(u>0)r[tot]=min(r[tot],(double)(xr-x)/u);
                if(u<0)r[tot]=min(r[tot],(double)(xl-x)/u);
                if(v>0)r[tot]=min(r[tot],(double)(yr-y)/v);
                if(v<0)r[tot]=min(r[tot],(double)(yl-y)/v);
            }
            else{
                if(u>0){//向右飞 
                    l[tot]=max(l[tot],(double)(xl-x)/u);//飞到左边界 
                    r[tot]=min(r[tot],(double)(xr-x)/u);//飞到右边界 
                }
                if(u<0){//向左飞 
                    l[tot]=max(l[tot],(double)(xr-x)/u);//飞到右边界
                    r[tot]=min(r[tot],(double)(xl-x)/u);//飞到左边界
                }
                
                if(v>0){//向上飞 
                    l[tot]=max(l[tot],(double)(yl-y)/v);
                    r[tot]=min(r[tot],(double)(yr-y)/v);
                }
                if(v<0){//向下飞 
                    l[tot]=max(l[tot],(double)(yr-y)/v);
                    r[tot]=min(r[tot],(double)(yl-y)/v);
                }
            }
        }
        //for(int i=1;i<=n;i++)printf("%.2lf %.2lf
    ",l[i],r[i]);
        for(int i=1;i<=tot;i++){
            h1[++cnt1]=l[i];
            h1[++cnt1]=r[i];
        }
        sort(h1+1,h1+cnt1+1);
        h[++cnt]=h1[1];
        for(int i=2;i<=cnt1;i++)
            if(h1[i]!=h1[i-1])h[++cnt]=h1[i];
        for(int i=1;i<=tot;i++){
            int pos=find(l[i]);
            sum[pos]++;
            pos=find(r[i]);
            sum[pos+1]--;
        }
        int mx=0,id=0;
        for(int i=1;i<=n;i++){
            sum[i]+=sum[i-1];
            if(sum[i]>mx)mx=sum[i],id=i;
        }
        printf("%.0lf",h[id]);
    }
    30分 算出所有弹幕出现的时间段+离散化+差分
    #include<cstdio>
    #include<algorithm>
    using namespace std;
    int INF=0x7fffffff;
    int in[100010]={0},out[100010]={0};
    int a[100010]={0};
    int main(){
        freopen("camera.in","r",stdin);
        freopen("camera.out","w",stdout);
        int i,n,xl,yl,xr,yr,cnt=1,sum=0,maxc=0,ans;
        scanf("%d%d%d%d%d",&n,&xl,&yl,&xr,&yr);
        for(i=0;i<n;i++){
            int x,y,u,v;
            int txs=-1,txe=INF,tys=-1,tye=INF,ts=-1,te=-1;
            scanf("%d%d%d%d",&x,&y,&u,&v);
            if((x<xl&&u<=0)||(x>xr&&u>=0))continue;
            if((y<yl&&v<=0)||(y>yr&&v>=0))continue;
            if(x>=xl&&x<=xr&&y>=yl&&y<=yr){
                ts=0;
                if(u==0&&v==0)te=INF;
                else if(u==0){
                    if(v>0)te=(yr-y)/v;
                    else{v=-v;te=(y-yl)/v;}
                }
                else if(v==0){
                    if(u>0)te=(xr-x)/u;
                    else{u=-u;te=(x-xl)/u;}
                }
                else{
                    if(u>0)txe=(xr-x)/u;
                    else{u=-u;txe=(x-xl)/u;}
                    if(v>0)txe=(yr-y)/v;
                    else{v=-v;tye=(y-yl)/v;}
                    te=min(txe,tye);
                }
            }
            else{
                if(u<0)u=-u;
                if(v<0)v=-v;
                if(u==0){
                    if(y
                    <=yl){tys=(yl-y+v-1)/v;tye=(yr-y)/v;}
                    if(y>=yr){tys=(y-yr+v-1)/v;tye=(y-yl)/v;}
                }
                else if(v==0){
                    if(x<=xl){txs=(xl-x+u-1)/u;txe=(xr-x)/u;}
                    if(x>=xr){txs=(x-xr+u-1)/u;txe=(x-xl)/u;}
                }
                else{
                    if(x<=xl){txs=(xl-x+u-1)/u;txe=(xr-x)/u;}
                    if(x>=xr){txs=(x-xr+u-1)/u;txe=(x-xl)/u;}
                    if(y<=yl){tys=(yl-y+v-1)/v;tye=(yr-y)/v;}
                    if(y>=yr){tys=(y-yr+v-1)/v;tye=(y-yl)/v;}
                }
                ts=max(txs,tys);
                te=min(txe,tye);
            }
            in[cnt]=ts;out[cnt++]=te;
        }
        for(i=1;i<=cnt-1;i++){a[in[i]]++;a[out[i]+1]--;}
        for(i=1;i<=cnt-1;i++){sum+=a[i];if(sum>maxc){maxc=sum;ans=i;}}
        printf("%d",ans);
        return 0;
    }
  • 相关阅读:
    HDU3910(数学期望题,题目难懂)
    HDU2389(二分图匹配Hopcroft-Carp算法)
    二分图详解
    巴什博弈、威佐夫博弈、尼姆博弈
    HDU2819(二分图匹配,记录过程)
    查找外键未创建索引
    acl使用示例
    oracle数据库备份任务
    集中备份相关
    集中备份项目实施方案
  • 原文地址:https://www.cnblogs.com/thmyl/p/7695734.html
Copyright © 2011-2022 走看看