zoukankan      html  css  js  c++  java
  • 猪猪大厦

    题目描述

    平面上有 n个无限长的不垂直或平行于地面的扶手电梯,可以看做一些一次函数,并且这些电梯方向均朝右即 x 轴正方向

    两个电梯的交点可以花费1代价换乘

    此时人物在第(x_1)个电梯的横坐标为$ y_1$ 位置。

    ( exttt{piggy})在第 (x_2)个电梯的横坐标为 (y_2) 位置。

    请问他最少花多少 代价才能过去?

    输入格式

    第一行一个正整数 n。

    第二行四个整数 x_1,y_1,x_2,y_2 。

    接下来 n 行,第 i 行两个数 k_i,b_i ,表示电梯的解析式为 y=k_ix+b_i

    输出格式

    最少花多少 代价如果无法到达,输出 -1。

    输入输出样例

    输入 #1

    1

    1 1 1 2

    50 -30

    输出 #1

    0

    输入 #2

    2

    1 2 2 2

    1 0

    2 0

    输出 #2

    -1

    输入 #3

    2

    1 -1 2 1

    1 0

    2 0

    输出 #3

    1

    说明/提示

    本题采用 Subtask。

    (Subtask1(20pts):1 le n le 10)

    (Subtask2(30pts):1 le nle 1000)

    (Subtask3(50pts):1 le x_1,x_2 le nle 10^5\-10^3 le y_1,y_2,k_i,b_i le 10^3)

    题目分析

    首先是结论:如果能到目标点,那么最多转换2次即可到达

    然后是特殊情况,如下:

    令起终点为(x1,y1),(x2,y2)

    1. 起点终点在同一直线,代价为0
    2. 起点所在直线(l_1)与终点所在直线(l_2)交点位于x1,x2之间,可以直接换乘1次
    3. 起终点直线交点不满足条件,通过第三方直线换乘2次。枚举换乘直线,判断交点顺序是否从左到右

    本题需要通过平面几何,考虑特殊情况

    #include <iostream>
    #include <cstdio>
    #include <algorithm>
    #include <cstring>
    using namespace std;
    struct Line
    {
        int k, b;
    } lines[100005];
    int n;
    int sx, sy, ex, ey;
    double getCrossX(int l1, int l2)
    {
        return (lines[l2].b - lines[l1].b)*1.0 / (lines[l1].k - lines[l2].k);
    }
    int main()
    {
        int l1, l2;
        double x1,x2;
        cin >> n;
        cin >> l1 >> x1 >> l2 >> x2;
        //注意数组是从0开始的
        l1--;l2--;
        for (int i = 0; i < n; i++)
        {
            scanf("%d%d", &lines[i].k, &lines[i].b);
        }
        sx = x1;
        ex = x2;
        //特判ans=0
        if (l1 == l2 && x1 <= x2)
        {
            cout << 0;
            return 0;
        }
        //特判ans=1
        if (lines[l1].k != lines[l2].k)
        {
            double cx = getCrossX(l1, l2);
            if (sx <= cx && ex >= cx)
            {
                cout << 1;
                return 0;
            }
        }else if (lines[l1].b==lines[l2].b){
            if (sx<=ex){
                cout<<1;
                return 0;
            }else{
                cout<<-1;
                return 0;
            }
        }
        //ans=2枚举过渡线
        for (int i = 0; i < n; i++)
            if (i != l1 && i != l2)
            {
                if (lines[l1].k != lines[i].k && lines[i].k != lines[l2].k)
                {
                    double cx1 = getCrossX(l1, i);
                    double cx2 = getCrossX(i, l2);
                    if (cx1 <= cx2 && x1 <= cx1 && x2 >= cx2)
                    {
                        cout << 2;
                        return 0;
                    }
                }
            }
        cout << -1;
    }
    
  • 相关阅读:
    在iphone上安装多个微信 【微信营销必备】
    微信 5.3 for iPhone已放出 微信iphone版更新下载
    支付宝也要上"服务号"?斗战微信继续升级
    微信事业群WXG成立 致力于打造微信大平台
    Matlab绘图系列之高级绘图
    朱亚东 临睡前发点鸡汤^^
    邢波老师致广大学员的一封信(2010-10-26)
    那些逐渐消失的技艺
    Nine Great Books about Information Visualization
    linux在shell中获取时间
  • 原文地址:https://www.cnblogs.com/Y-E-T-I/p/15129613.html
Copyright © 2011-2022 走看看