zoukankan      html  css  js  c++  java
  • Codeforces gym102058 J. Rising Sun-简单的计算几何+二分 (2018-2019 XIX Open Cup, Grand Prix of Korea (Division 2))

    time limit per test
    1.0 s
    memory limit per test
    1024 MB
    input
    standard input
    output
    standard output

    Joon has a midterm exam tomorrow, but he hasn't studied anything. So he decided to stay up all night to study. He promised himself that he will not stop studying before the sun rises.

    Joon's house is in some mountains. For convenience, let's say that Joon is living in a 2-dimensional coordinate system. The mountains are in the region y0y≥0, starting at x=a0x=a0, and the boundary of them consists of 2n2n line segments parallel to either y=xy=x or y=xy=−x.

    More precisely, the boundary of the mountains can be described by (2n1)(2n−1) additional integers, where the iith number aiai of them is the xx-coordinate of the iith cusp of the mountains. The boundary line starts at (a0,0)(a0,0), proceeds parallel to y=xy=x until its xx-coordinate reaches a1a1, then proceeds parallel to y=xy=−x until its xx-coordinate reaches a2a2, and so on. After the last step, the line proceeds parallel to y=xy=−x until it meets the xx-axis.

    The interior of the mountains is the region below the boundary and above the xx-axis. Thus, the interior and the boundary are disjoint.

    At some point between x=a0x=a0 and x=a2n1x=a2n−1, there is Joon's house on the boundary of the mountains. The size of his house is neglectable compared to the mountains.

    Currently, the sun is at the origin and it rises vertically (+y+y direction), 1 per minute. Joon can see the sun if the interior of the mountains does not intersect the straight line segment connecting Joon's house and the sun. Joon is completely exhausted and wants to know when can he stop studying. But as you may expect, he is out of his mind, so he cannot do such difficult math. Help him!

    Input

    The first line of the input contains an integer nn (1n1031≤n≤103).

    The next line contains 2n2n integers, the iith of which is the integer ai1ai−1 (1a0<<a2n11061≤a0<⋯<a2n−1≤106).

    The last line contains an integer xx, the xx-coordinate of Joon's house (a0xa2n1a0≤x≤a2n−1).

    It is guaranteed that the boundary of the mountains is in the region y0y≥0.

    Output

    Print exactly one integer mm, the smallest integer such that Joon can see the sun after mm minutes.

    Examples
    input
    Copy
    2
    1 4 6 7
    7
    output
    Copy
    5
    input
    Copy
    2
    3 4 5 7
    7
    output
    Copy
    0
    input
    Copy
    3
    4 9 12 13 14 16
    15
    output
    Copy
    8
    Note

    Figure: Illustration of the first example.

     

     题意就是给你山头的横坐标x,然后山的轮廓是一个山头到另一个山头的形状是与y=x或者y=-x平行的,坐标奇数是y=x平行的,偶数是与y=-x平行的,然后给你小孩家坐标的横坐标,他家在山的轮廓线上。

    太阳沿着y轴垂直上升,一分钟还是一小时(忘了)上升1米,问你他什么时候能看到太阳。

    直接先算出每个山头的横坐标,然后算出来小孩家的纵坐标,然后二分太阳的高度,通过太阳的坐标和小孩家的坐标,推出来直线的方程式,然后枚举每个山头,算出高度与实际的高度比较一下就可以了。

    一开始直接枚举山头算直线,最后小数上取整,没过,改了二分过的,而且二分右界一开始设的1e6,wa44,改成1e8过的。。。

    题目也小小暗示了二分,因为输出的是一个整数,OK

    代码:

     1 #include<bits/stdc++.h>
     2 using namespace std;
     3 typedef long long ll;
     4 const int maxn=1e6+10;
     5 const int inf=0x3f3f3f3f;
     6 
     7 double a[maxn],b[maxn];
     8 
     9 int main()
    10 {
    11     int n,pos;
    12     cin>>n;
    13     for(int i=1;i<=2*n;i++)
    14         cin>>a[i];
    15     cin>>pos;
    16     double x,y;
    17     double bb;
    18     for(int i=1;i<2*n;i++){
    19         x=a[i];y=b[i];
    20         if(i%2!=0){
    21             bb=y-x;
    22             x=a[i+1];y=x+bb;b[i+1]=y;
    23         }
    24         else{
    25             bb=y+x;
    26             x=a[i+1];y=(-1)*x+bb;b[i+1]=y;
    27         }
    28     }
    29     x=a[2*n];y=b[2*n];
    30     bb=y+x;
    31     x=bb;y=0;a[2*n+1]=x;b[2*n+1]=0;
    32 //    for(int i=1;i<=2*n+1;i++){
    33 //        cout<<"("<<a[i]<<","<<b[i]<<")"<<endl;
    34 //    }
    35     int cnt=0;
    36     double X=pos,Y;
    37     for(int i=1;i<=2*n+1;i++){
    38         if(a[i]<X&&a[i+1]>=X){
    39             cnt=i+1;
    40             double k=(b[i]-b[i+1])/(a[i]-a[i+1]);
    41             double bb=b[i]-k*a[i];
    42             Y=k*X+bb;
    43             break;
    44         }
    45     }
    46     int ans=inf;
    47 //    for(int i=1;i<cnt;i++){
    48 //        double k=(Y-b[i])*1.0/(X-a[i]);
    49 //        double bb=Y-k*X;
    50 //        int flag=0;
    51 //        for(int i=1;i<cnt;i++){
    52 //            double h=k*a[i]+bb;
    53 //            if(h>=b[i]) continue;
    54 //            else{flag=1;break;}
    55 //        }
    56 //        if(flag==0) ans=min(ans,bb);
    57 //    }
    58 //    ans=ceil(ans);
    59 //    if(ans==-0) ans=0;
    60     int l=0,r=1e8+10;
    61     while(l<=r){
    62         int mid=(l+r)>>1;
    63         double k=(Y-mid)/X;
    64         double bb=Y-k*X;
    65         int flag=0;
    66         for(int i=1;i<cnt;i++){
    67            double h=k*a[i]+bb;
    68            if(h>=b[i]) continue;
    69            else{flag=1;break;}
    70         }
    71         if(flag==0) r=mid-1,ans=min(ans,mid);
    72         else l=mid+1;
    73     }
    74     cout<<ans<<endl;
    75 }
  • 相关阅读:
    我的DBDA类文件
    登录时的验证码怎么写?
    phpcms 制作简单企业站的常用标签
    HTML 基础知识
    目标
    split函数的实现
    myString操作符重载
    cout中的执行顺序_a++和++a
    二叉树的层次遍历法
    树的前中序遍历_求后续遍历
  • 原文地址:https://www.cnblogs.com/ZERO-/p/10294571.html
Copyright © 2011-2022 走看看