• 【2017杭二联考】穿越矩形


    P2554 - 【2017杭二联考】穿越矩形

    Description

    题目背景: 
    幻想乡的创始人之一,八云紫,有着强大的控制结界的能力,可以瞬间消除一定范围内 所有弹幕。我们可以将其消除范围视为一个矩形,而弹幕可以视为动点。 
    八云紫想要嘲讽她的敌人,所以她希望只使用一次消除能力,尽可能多地消除弹幕。 
    请你告诉她,在哪一时刻使用道具,可以消除尽可能多的弹幕。

    问题描述: 
    在平面上给定一个矩形区域(也可能退化成线段或者点)。 矩形的边与坐标轴平行,左下端 点为 (xl,yl),右上端点为 (xr,yr)。 
    给定 n 个动点,初始坐标为 (xi, yi),运动方向为 (ui,vi),速度为 sqrt((ui)2+(vi)2)sqrt((ui)2+(vi)2) 求在哪一时刻 t ( t ∈N ),在矩形内部及边界的动点数目最多。 
    如果有多个 t 满足条件,输出最小的 t 即可。

    Input

    第一行 5 个正整数,n, xl, yl, xr, yr,表示动点个数和矩形区域。 
    接下来 n 行,每行 4 个整数,xi, yi, ui, vi ,描述第 i 个动点。

    Output

    在矩形内部及边界的动点数目最多的时刻 t ( t ∈N )。 
    如果有多个 t 满足条件,输出最小的 t 即可。

    Sample Input

    2 2 2 3 3 
    3 1 -1 1 
    2 3 1 -1

    Sample Output

    1

    Hint

    数据范围: 
    对于前 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 均为整数.

    Source

    数学,计算几何

    考试时看错题目了,以为方向指的是从原点向给出的 (ui,vi)走(我以为是一个坐标),然后就GG了。。。

    首先明确(ui,vi)是一个向量,由于速度是sqrt((ui)2+(vi)2)sqrt((ui)2+(vi)2),向量分解一下就是横坐标+u,纵坐标+v,然后模拟每一秒的运动情况,再判断,就可获得40分。(详见work()函数)

    一百分的做法呢?我们发现其实只要知道在哪一个时间段内点在矩形上或中就可以了。我们预处理出每个点在矩形内部的时间(用临界点计算),再将时间离散化,将每个点的时间差分,最后o(n)取最大即可。

    交了一发WA了,90分,不知道错了哪里。。。发现是小数据WA了,就可耻的加了个work()暴力程序去算。。。

     1 #include<cstdio>
     2 #include<cstdlib>
     3 #include<cstring>
     4 #include<iostream>
     5 #include<cmath>
     6 #include<algorithm>
     7 #include<vector>
     8 #include<stack>
     9 #include<queue>
    10 #include<map>
    11 #define RG register
    12 #define IL inline
    13 #define pi acos(-1.0)
    14 #define ll long long 
    15 using namespace std;
    16 struct point{
    17   int x,y,u,v;
    18 };
    19 point a[100005];
    20 int n,xl,yl,xr,yr,cnt=0;
    21 int in[100005],out[100005];
    22 int l[100005],r[100005];
    23 int F[200005],rak[200005];
    24 int c[200005];
    25 map <int,int> s;
    26 void work(){
    27   int T=0,cnt=0,maxn=0;
    28   for(int t=1;   ;t++){
    29      int ans=0;
    30      for(int j=1;j<=n;j++){
    31        a[j].x+=a[j].u;
    32        a[j].y+=a[j].v;//分解向量
    33        ++cnt;
    34        if(a[j].x>=xl&&a[j].x<=xr&& a[j].y>=yl&& a[j].y<=yr)  ++ans;
    35        if(cnt>=10000000){
    36         printf("%d",T);
    37         exit(0);
    38         }
    39      }
    40      if(ans>maxn)  maxn=ans,T=t;
    41      if(cnt>=10000000){
    42      printf("%d",T);
    43      exit(0);
    44      }
    45   }
    46 }
    47 int main() {
    48   scanf("%d%d%d%d%d",&n,&xl,&yl,&xr,&yr);
    49   for(int i=1;i<=n;i++)  scanf("%d%d%d%d",&a[i].x,&a[i].y,&a[i].u,&a[i].v);
    50   if(n<=100) work();
    51   for(int i=1;i<=n;i++){
    52     int txl,txr,tyl,tyr;
    53     if((a[i].u==0)&&(a[i].x<xl||a[i].x>xr)) continue;
    54     if((a[i].v==0)&&(a[i].y<yl||a[i].y>yr)) continue;//不可能成立直接判断掉
    55     if(a[i].u==0) txl=0,txr=999999999;
    56     else{
    57        txl=(xl-a[i].x)%a[i].u==0?(xl-a[i].x)/a[i].u:(xl-a[i].x-1)/a[i].u+1;
    58        txr=(xr-a[i].x)/a[i].u;
    59        if(a[i].u<0) swap(txl,txr);
    60     }
    61     if(a[i].v==0) tyl=0,tyr=999999999;
    62     else{
    63        tyl=(yl-a[i].y)%a[i].v==0?(yl-a[i].y)/a[i].v:(yl-a[i].y-1)/a[i].v+1;
    64        tyr=(yr-a[i].y)/a[i].v;
    65        if(a[i].v<0) swap(tyl,tyr);
    66     }
    67     if(txl<0) txl=0; if(txr<0) txr=-1;
    68     if(tyl<0) tyl=0; if(tyr<0) tyr=-1;
    69     int L=max(txl,tyl),R=min(txr,tyr);
    70     if(L>R) continue;
    71     ++cnt;
    72     l[cnt]=L,r[cnt]=R;
    73   }
    74   for(int i=1;i<=cnt;i++)  F[++F[0]]=l[i],F[++F[0]]=r[i];
    75   sort(F+1,F+F[0]+1);
    76   int tep=0;
    77   for(int i=1;i<=F[0];i++)
    78       if(i==1||F[i]!=F[i-1]) s[F[i]]=++tep,rak[tep]=F[i];
    79   for(int i=1;i<=cnt;i++){
    80       c[s[l[i]]]++;
    81       c[s[r[i]]+1]--;
    82   }
    83   int maxn=0,T=0,j=0;
    84   for(int i=1;i<=tep;i++){
    85       j+=c[i];
    86       if(j>maxn)  maxn=j,T=i;
    87   }
    88   printf("%d",rak[T]);
    89   return 0;
    90 }
  • 相关阅读:
    禁止网页后退
    C# 数组排序
    SQL求往年的工资和
    手机的隐秘功能
    C#中的String类
    C#修饰符
    Application,Session,Cookie,ViewState和Cache区别
    css margin和padding的区别
    php常见的js正则表达式
    js 正则表达式基础篇
  • 原文地址:https://www.cnblogs.com/cjoier-nfy/p/7407403.html
Copyright © 2020-2023  润新知