zoukankan      html  css  js  c++  java
  • POJ 1039 (求线段交点 + 思维)

    题目:传送门

    题意:有一个 n 个拐点的曲折的管道,你有一束光射进去(直射),问你最远能射到点的 x 坐标是多大。

          1 <= n <= 20

     

    思路:首先需要想到,这条线肯定是经过管道的一个上拐点和一个下拐点。

       然后就枚举所有情况就行了。

    #include <iostream>
    #include <stdio.h>
    #include <string.h>
    #include <algorithm>
    #include <queue>
    #include <map>
    #include <vector>
    #include <set>
    #include <string>
    #include <math.h>
    #define LL long long
    #define mem(i, j) memset(i, j, sizeof(i))
    #define rep(i, j, k) for(int i = j; i <= k; i++)
    #define dep(i, j, k) for(int i = k; i >= j; i--)
    #define pb push_back
    #define make make_pair
    #define INF INT_MAX
    #define inf LLONG_MAX
    #define PI acos(-1)
    using namespace std;
    
    const int N = 1e2 + 5;
    const double eps = 1e-10;
    
    struct Point {
        double x, y;
        Point(double x = 0, double y = 0) : x(x), y(y) { }
    };
    
    int dcmp(double x) {
        if(fabs(x) < eps) return 0; else return x < 0 ? -1 : 1;
    }
    
    Point operator + (Point A, Point B) { return Point(A.x + B.x, A.y + B.y); }
    Point operator - (Point A, Point B) { return Point(A.x - B.x, A.y - B.y); }
    Point operator * (Point A, double p) { return Point(A.x * p, A.y * p); }
    Point operator / (Point A, double p) { return Point(A.x / p, A.y / p); }
    
    double Cross(Point A, Point B) { return A.x * B.y - A.y * B.x; }
    double Dot(Point A, Point B) { return A.x * B.x + A.y * B.y; }
    
    inline Point GLI(Point P, Point v, Point Q, Point w) {///求直线p + v*t 和 Q + w*t 的交点,需确保有交点,v和w是方向向量
        Point u = P - Q;
        double t = Cross(w, u) / Cross(v, w);
        return P + v * t;
    }
    
    inline bool LSPI(Point b1, Point b2, Point a1, Point a2) { /// 判断直线b1b2是否与线段a1a3相交
        return dcmp(Cross(b1 - a1, b2 - a1)) * dcmp(Cross(b1 - a2, b2 - a2)) <= 0;
    }
    
    Point up[N], dw[N];
    
    int main() {
    
        int n;
        while(scanf("%d", &n) && n) {
            rep(i, 1, n) {
                scanf("%lf %lf", &up[i].x, &up[i].y);
                dw[i].x = up[i].x;
                dw[i].y = up[i].y - 1;
            }
            bool flag = 0;
            double ans = -100000000.0;
            rep(i, 1, n) rep(j, i + 1, n) {
                int pos;
                for(pos = 1; pos <= n; pos++) if(LSPI(up[i], dw[j], up[pos], dw[pos]) == false) break;
                if(pos > n) { flag = 1; break; }
                if(pos > j) {
                    if(LSPI(up[i], dw[j], up[pos], up[pos - 1])) {
                        Point tmp = GLI(up[i], dw[j] - up[i], up[pos], up[pos - 1] - up[pos]);
                        ans = max(ans, tmp.x);
                    }
                    if(LSPI(up[i], dw[j], dw[pos], dw[pos - 1])) {
                        Point tmp = GLI(up[i], dw[j] - up[i], dw[pos], dw[pos - 1] - dw[pos]);
                        ans = max(ans, tmp.x);
                    }
                }
    
                for(pos = 1; pos <= n; pos++) if(LSPI(dw[i], up[j], up[pos], dw[pos]) == false) break;
                if(pos > n) { flag = 1; break; }
                if(pos > j) {
                    if(LSPI(dw[i], up[j], up[pos], up[pos - 1])) {
                        Point tmp = GLI(dw[i], up[j] - dw[i], up[pos], up[pos - 1] - up[pos]);
                        ans = max(ans, tmp.x);
                    }
                    if(LSPI(dw[i], up[j], dw[pos], dw[pos - 1])) {
                        Point tmp = GLI(dw[i], up[j] - dw[i], dw[pos], dw[pos - 1] - dw[pos]);
                        ans = max(ans, tmp.x);
                    }
                }
                if(flag) break;
            }
            if(flag) puts("Through all the pipe.");
            else printf("%.2f
    ", ans);
        }
        return 0;
    }
    一步一步,永不停息
  • 相关阅读:
    Linux常用命令
    Springboot环境搭建_第一个例子
    java 填写一个银行卡如何判断是否真实存在
    java 理解如何实现图片验证码 傻瓜都能看懂。
    编程语言学习路线··
    他他他她她她所唱所写………
    Docker 学习笔记 (4)
    Docker 学习笔记 (3)
    Docker 学习笔记 (2)
    Docker 学习笔记 (1)
  • 原文地址:https://www.cnblogs.com/Willems/p/12392085.html
Copyright © 2011-2022 走看看