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

  • 相关阅读:
    私有构造函数(C# 编程指南)
    unshift(), push(),shift(),pop()函数的运用
    flex转载
    二叉树各节点的实现
    关于删除树中指定节点的实例分析
    树的各种操作代码实现
    关于二叉查找树的++迭代器的实现
    利用map,以一个单词为键,以与它相差一个字母的单词组集作为值的算法编程
    逆向单项链表的算法
    给Vector类添加insert
  • 原文地址:https://www.cnblogs.com/LJ-blog/p/4023080.html
Copyright © 2011-2022 走看看