zoukankan      html  css  js  c++  java
  • URAL 1990 Podracing

    计算几何。。首先题意很难懂,多亏了纬哥解释,才懂。。

    就是有左边有一条折线,右边有一条折线,两条折线的起点和终点的纵坐标相同,还有一些摄像头,一条线段平行x轴的线段从起点到终点,必须得在两条折线中间,并且不能碰到摄像头,问线段最长的长度

    其实不难的,思路很快就有了,先o(n)处理左边折线的点到右边的折线的水平长度以及右边的点到左边的点的长度,然后再求摄像头到左右两条折线的水平长度。。不过wa了,我们很快发现了错误在哪,就是摄像头的纵坐标有可能相同,还有y轴坐标大于或者小于折线的终点和起点的摄像头都不能算进去,不过最后还是写挫了,没有ac,今天终于ac了。。

      1 #include <iostream>
      2 #include <cstdio>
      3 #include <cstring>
      4 #include <cmath>
      5 #include <algorithm>
      6 #include <map>
      7 
      8 using namespace std;
      9 
     10 #define LL long long
     11 #define eps 1e-12
     12 #define mnx 100020
     13 #define mxe 2000020
     14 #define inf 1e12
     15 #define Pi acos( -1.0 )
     16 
     17 //精度
     18 int dcmp( double x ){
     19     if( fabs( x ) < eps ) return 0;
     20     return x < 0 ? -1 : 1;
     21 }
     22 //
     23 struct point{
     24     double x, y;
     25     point( double x = 0, double y = 0 ) : x(x), y(y) {}
     26     point operator + ( const point &b ) const{
     27         return point( x + b.x, y + b.y );
     28     }
     29     point operator - ( const point &b ) const{
     30         return point( x - b.x, y - b.y );
     31     }
     32     point operator * ( const double &k ) const{
     33         return point( x * k, y * k );
     34     }
     35     point operator / ( const double &k ) const{
     36         return point( x / k, y / k );
     37     }
     38     bool operator < ( const point &b ) const{
     39         return dcmp( y - b.y ) < 0 || dcmp( y - b.y ) == 0 && dcmp( x - b.x ) < 0;
     40     }
     41     bool operator == ( const point &b ) const{
     42         return dcmp( x - b.x ) == 0 && dcmp( y - b.y ) == 0;
     43     }
     44     double len(){
     45         return sqrt( x * x + y * y );
     46     }
     47     void input(){
     48         scanf( "%lf%lf", &x, &y );
     49     }
     50 };
     51 typedef point Vector;
     52 // 点积
     53 double dot( Vector a, Vector b ){
     54     return a.x * b.x + a.y * b.y;
     55 }
     56 // 叉积
     57 double cross( Vector a, Vector b ){
     58     return a.x * b.y - a.y * b.x;
     59 }
     60 int n, m, q;
     61 point a[mnx], b[mnx], c[mnx];
     62 double calc( point p0, point p1, point p2  ){
     63     if(dcmp(p1.y - p2.y) == 0) {
     64         return min((p0 - p1).len(), (p0 - p2).len());
     65     }
     66     if( p1.y > p2.y ) swap( p1, p2 );
     67     double t = (p0.y - p1.y) / ( p2.y - p1.y );
     68     point v = p1 + ( p2 - p1 ) * t;
     69     return ( p0 - v ).len();
     70 }
     71 void solve(){
     72     double ans = inf;
     73     int j = 0;
     74     for( int i = 0; i < n; i++ ){
     75         while( j < m-1 ){
     76             if( dcmp(a[i].y-b[j].y) >= 0 && dcmp(a[i].y-b[j+1].y) <= 0 ){
     77                 ans = min( ans, calc( a[i], b[j], b[j+1] ) );
     78                 break;
     79             }
     80             else j++;
     81         }
     82     }
     83     j = 0;
     84     for( int i = 0; i < m; i++ ){
     85         while( j < n-1 ){
     86             if( dcmp(b[i].y-a[j].y) >= 0 && dcmp(b[i].y-a[j+1].y) <= 0 ){
     87                 ans = min( ans, calc( b[i], a[j], a[j+1] ) );
     88                 break;
     89             }
     90             else j++;
     91         }
     92     }
     93     sort( c, c + q );
     94     int cnt = 0;
     95     for( int i = 0; i < q; i++ ){
     96         if( dcmp(c[i].y-a[0].y) < 0 || dcmp(c[i].y-a[n-1].y) > 0 ) continue;
     97         c[cnt++] = c[i];
     98     }
     99     q = cnt;
    100     int i = 0; j = 0;
    101     for( int k = 0; k < q; k++ ){
    102         double res = -inf;
    103         int cur = k;
    104         while( cur < q && dcmp(c[cur+1].y - c[cur].y) == 0 ) cur++;
    105         int tmp = cur;
    106 
    107         while( i < n-1 ){
    108             if( dcmp(c[k].y-a[i].y) >= 0 && dcmp(c[k].y-a[i+1].y) <= 0 )
    109                 break;
    110             else i++;
    111         }
    112         while( j < m-1 ){
    113             if( dcmp(c[k].y-b[j].y) >= 0 && dcmp(c[k].y-b[j+1].y) <= 0 )
    114                 break;
    115             else j++;
    116         }//cout << k << " " << cur << endl;
    117         for( int u = k; u < cur; u++ ){
    118             if( cross( c[u] - a[i], a[i+1] - a[i] ) < 0 ) k++;
    119             else break;
    120         }
    121         for( int u = cur; u > k; u-- ){
    122             if( cross( c[u] - b[j], b[j+1] - b[j] ) > 0 ) cur--;
    123             else break;
    124         }
    125         res = max( res, calc( c[k], a[i], a[i+1] ) );
    126         res = max( res, calc( c[cur], b[j], b[j+1] ) );
    127         //printf( "%.5lf
    ", res );
    128         for( int u = k; u < cur; u++ ){
    129             res = max( res, ( c[u+1] - c[u] ).len() );
    130         }
    131         ans = min( res, ans );
    132         k = tmp;
    133     }
    134     printf( "%.8lf
    ", ans );
    135 }
    136 int main(){
    137     while( scanf( "%d", &n ) != EOF ){
    138         for( int i = 0; i < n; i++ )
    139             a[i].input();
    140         scanf( "%d", &m );
    141         for( int i = 0; i < m; i++ )
    142             b[i].input();
    143         scanf( "%d", &q );
    144         for( int i = 0; i < q; i++ )
    145             c[i].input();
    146         solve();
    147     }
    148     return 0;
    149 }
    View Code

    附数据

    4
    0 0
    5 5
    9 12
    8 15
    4
    8 0
    11 7
    12 10
    12 15
    7
    7 4
    5 8
    6 8
    9 8
    11 8
    14 8
    16 8

    answer: 2.28571429

  • 相关阅读:
    sqlhelper使用指南
    大三学长带我学习JAVA。作业1. 第1讲.Java.SE入门、JDK的下载与安装、第一个Java程序、Java程序的编译与执行 大三学长带我学习JAVA。作业1.
    pku1201 Intervals
    hdu 1364 king
    pku 3268 Silver Cow Party
    pku 3169 Layout
    hdu 2680 Choose the best route
    hdu 2983
    pku 1716 Integer Intervals
    pku 2387 Til the Cows Come Home
  • 原文地址:https://www.cnblogs.com/LJ-blog/p/4023080.html
Copyright © 2011-2022 走看看