zoukankan      html  css  js  c++  java
  • poj 1755 Triathlon 半平面交求不等式的 是否为空集-------构造有向直线

    题目来源:

    http://poj.org/problem?id=1755

    分析:

    设比赛总长度为 1, 其中游泳长度为x, 自行车长度为y, 赛跑长度为 1 - x - y, 则选手 i 打败 选手j (不能并列) 的条件是

    x / v[i] + y / u[i] + (1 - x - y) / w[i]  <  x / v[j] + y / u[j] + (1 - x - y) / w[j]  

    整理为 a*x + b * y + c > 0 (直线向量为 (b , -a))   ,  为逆时针直线方向(平面在直线的左侧)

    a = (1 / v[j]  - 1 / w[j])  - ( 1 / v[i] - 1 / w[i] )

    b = (1 / u[j]  - 1 / w[j])  - ( 1 / u[i] - 1 / w[i] )

    c = 1/ W[j] - 1/ W[i]

    为了 降低 精度, 我们 可以 都乘以 一个 数 val

    a = (val/ v[j]  - val / w[j])  - ( val / v[i] - val / w[i] )   b, c 同理

    这样 每个选手i , 得到 n- 1 个半平面 ,  注意 , 这里 要加上 题目要求的 x > 0 y > 0 1 - x - y >0 这三个 固定约束 , 一共是 n + 2 个半平面

    代码如下:

    double V[Max_N] , U[Max_N] , W[Max_N] ;
    int main(){
        int t, i , j , ln ,n , k;
        double a,b,c;
        scanf("%d",&n) ;
        for(i = 0 ; i< n ; i++)
            scanf("%lf%lf%lf", &V[i], &U[i], &W[i]) ;
        for(i = 0 ; i< n ; i++){
            k = 0 ;
            double val = 10000 ;
            for(j = 0 ; j < n; j++){ //构造有向直线 ax + by + c > 0 , 有向(b, -a)对应是逆时针
                if( j != i){
                    if(V[i] <= V[j] && U[i] <= U[j] && W[i] <= W[j]) { //特判
                        break;
                    }
                    if( V[i] >= V[j] && U[i] >= U[j] && W[i] >= W[j] ) //特判
                        continue ;
                    a = (val / V[j] - val / W[j] ) - (val / V[i] - val / W[i]) ;
                    b = (val / U[j] - val / W[j] ) - (val / U[i] - val / W[i]) ;
                    c = val / W[j] - val / W[i] ;
                    if(fabs(a) < fabs(b)) // 防止b 为0
                        List[k].s = Point( 0 , - c / b) ;
                    else
                        List[k].s = Point( - c / a , 0) ;
                    List[k].e = List[k].s + Point(b, -a) ;
                    k++;
                 }
            }
            if(j != n) {printf("No
    ") ; continue ;}
            //由题意增加的三个平面 x > 0 y > 0 , x + y < 1(总长度为1)
            List[k++] = pVector( Point(0, 0) , Point( 1, 0) ) ;
            List[k++] = pVector(Point( 0 , 1) , Point(0 , 0 ) ) ;
            List[k++] = pVector(Point( 0 , 1) , Point(-1 , 2 ) ) ;
            if(  halfPanelCross(List , k)  ) // 并列冠军不算,故用的面积计算的, 但是测试不用面积用顶点也ac?
                printf("Yes
    ") ;
            else printf("No
    ") ;
        }
        return 0;
    }
  • 相关阅读:
    重温spark基本原理
    hive拉链表以及退链例子笔记
    org.apache.hadoop.hive.ql.exec.DDLTask. MetaException错误问题
    skywalking部署
    【机器学习实战】第5章 Logistic回归
    【机器学习实战】第4章 基于概率论的分类方法:朴素贝叶斯
    【机器学习实战】第3章 决策树
    Apache Spark 2.2.0 中文文档
    Apache Spark 2.2.0 中文文档
    Apache Spark 2.2.0 中文文档
  • 原文地址:https://www.cnblogs.com/zn505119020/p/3701470.html
Copyright © 2011-2022 走看看