zoukankan      html  css  js  c++  java
  • 11.02T1 几何

    倾斜的线

    (slope.cpp)

    【问题描述】

    给定两个正整数PQ。在二维平面上有n个整点。现在请你找到一对点使得经过它们的直线的斜率在数值上最接近P/Q(即这条直线的斜率与P/Q的差最小),请输出经过它们直线的斜率p/q。如果有两组点的斜率的接近程度相同,请输出较小的斜率。保证答案的p/q> 0,即输出的pq都是正整数。

    【输入格式】

    输入文件名为slope.in

    第一行三个正整数n P Q

    接下来n行每行两个正整数x y表示一个点的坐标。保证不存在x坐标相同或者y坐标相同的点(即斜率不会为无穷大与0)。

    【输出格式】

    输出文件名为slope.out

    输出仅一行,格式为p/q,表示最接近的斜率,其中pq都是正整数。

    【样例输入与输出】

    example_slope1.in

    example_slope1.out

    6 15698 17433

    112412868 636515040

    122123982 526131695

    58758943 343718480

    447544052 640491230

    162809501 315494932

    870543506 895723090

    193409386/235911335

           更多样例请见example/slope/目录。

    【数据范围】

    对于1~10号测试点(50%):n<=1000。

    对于所有测试点(100%):n<=400000。

    把所有点按照P/Q斜率投射到y轴上排序,可以证明相邻的点对应的线段一定有一条是最优解,因为不相邻的点与给定的斜率夹角比相邻的大

    code:

     1 #include<iostream>
     2 #include<cstdio>
     3 #include<algorithm>
     4 #include<cmath>
     5 #define N 1000006 
     6 using namespace std;
     7 struct node{
     8     long double x,y,w;
     9 }e[N];
    10 bool cmp(const node&a,const node&b){
    11     return a.w<b.w;
    12 }
    13 long double getk(int i,int j){
    14     return (e[i].y-e[j].y)/(e[i].x-e[j].x);
    15 }
    16 int gcd(int a,int b){
    17     if(a<b)swap(a,b);
    18     while(a=a%b)swap(a,b);
    19     return b;
    20 }
    21 int main(){
    22     int n;
    23     long double P,Q;
    24     cin>>n>>P>>Q;
    25     for(int i=1;i<=n;i++){
    26         cin>>e[i].x>>e[i].y;
    27         e[i].w=e[i].y-e[i].x*P/Q;
    28     }
    29     sort(e+1,e+n+1,cmp);
    30     long double delta=9999999.0;
    31     int now1,now2;
    32     for(int i=1;i<n;i++){
    33         if(fabs(getk(i,i+1)-P/Q)<delta){
    34             now1=i,now2=i+1;
    35             delta=fabs(getk(i,i+1)-P/Q);
    36         }
    37         else if(fabs(getk(i,i+1)-P/Q)==delta){
    38             if(getk(i,i+1)-P/Q<0){
    39                 now1=i,now2=i+1;
    40             }
    41         }
    42     }
    43     int deltax=e[now1].x-e[now2].x,deltay=e[now1].y-e[now2].y;
    44     if(deltax<0)deltax=-deltax,deltay=-deltay;
    45     int GCD=gcd(abs(deltax),abs(deltay));
    46     cout<<deltay/GCD<<"/"<<deltax/GCD;
    47     return 0;
    48 }

    over

  • 相关阅读:
    批处理读取INI文件
    重装操作系统的20条原则
    SATA串口硬盘Windows Vista系统驱动安装实录
    中国国家地理高清晰的PDF书籍系列经典珍藏版
    单一职责原则
    理解boost::bind的实参传递方式
    理解C++ dynamic_cast
    C# vs C++之三:静态构造函数
    TDD可以驱动设计吗?
    依赖注入与对象间关系
  • 原文地址:https://www.cnblogs.com/saionjisekai/p/9898487.html
Copyright © 2011-2022 走看看