51nod 1100 斜率最大

来源:互联网 发布:hadoop 知乎 编辑:程序博客网 时间:2024/06/05 06:11

平面上有N个点,任意2个点确定一条直线,求出所有这些直线中,斜率最大的那条直线所通过的两个点。
(点的编号为1-N,如果有多条直线斜率相等,则输出所有结果,按照点的X轴坐标排序,正序输出。数据中所有点的X轴坐标均不相等,且点坐标为随机。)
Input
第1行,一个数N,N为点的数量。(2 <= N <= 10000)第2 - N + 1行:具体N个点的坐标,X Y均为整数(-10^9 <= X,Y <= 10^9)
Output
每行2个数,中间用空格分隔。分别是起点编号和终点编号(起点的X轴坐标 < 终点的X轴坐标)
Input示例
51 26 84 45 42 3
Output示例
4 2

  学校老司机建议写下自己当时思路,有利于以后复习,一开始还没怎么在意,今天看两周前的题目居然忘了怎么做,吓得我马上开了个博客,主要是学习过程,非大神,看官们轻喷

  

  首先看了这道题第一感觉是暴力(菜鸡只能暴力), 最暴力的方法就是两个for循环,比较斜率,估计会爆所以跳过

         1  :将点首先按x坐标排序,有利于保存答案和优化

         2  :计算过程保存一个最高y点,在x增大的情况下y如果一样大,肯定斜率更低。

         3  :保存的话用数组保存两个点的x值,因为题目x都不相同,题目要求输出原来的数组的顺序点,所以开个数组保存原顺序,然后算出答案从中匹配

       附上代码:

    

#include<iostream>#include <algorithm>#include <string.h>#include <string>#include <stack>#include<cstdio>using namespace std;   long long int n,i,j,ansnum=0,ymax=0,temp,shunxu[10005],ax=0,ay=0;   double xielv=0,txielv; struct dian    {     long long   int  x,y;    }d[10005],ans[10005];int cmp(dian a,dian b){    if(a.x<b.x)        return 1;    return 0;}int main(){   scanf("%lld",&n);   for(i=0;i<n;i++)   {    scanf("%lld%lld",&d[i].x,&d[i].y);    shunxu[i]=d[i].x;   }   sort(d,d+n,cmp);   temp=n-1;   for(i=0;i<temp;i++)   {       ymax=d[i].y;       for(j=i+1;j<=temp;j++)       {           if(d[j].y<=ymax)            continue;            if(d[j].y<=d[i].y)                continue;            txielv=(double(d[j].y-d[i].y))/(double(d[j].x-d[i].x));           if(txielv>xielv)           {               ymax=d[j].y;               xielv=txielv;               ans[0].x=d[i].x;               ans[0].y=d[j].x;               ansnum=1;           }           else if(txielv==xielv)           {               ans[ansnum].x=d[i].x;               ans[ansnum].y=d[j].x;           }       }   }     for(i=0;i<ansnum;i++)     {         for(j=0;j<n;j++)         {             if(shunxu[j]==ans[i].x)                ax=j+1;             else if(shunxu[j]==ans[i].y)                ay=j+1;         }         printf("%lld %lld\n",ax,ay);     }    return 0;}

然后发现别人的代码都是20ms以内

发现有个数学规律,排序后斜率最大的两个点肯定是相邻的,用反证法更容易验证,那我写那么多干吗唉

附上代码:

#include<iostream>#include <algorithm>#include <string.h>#include <string>#include <stack>#include<cstdio>#include <set>#include<queue>using namespace std;   long long int n,i,j,ansnum=0,ymax=0,temp,shunxu[10005],ax=0,ay=0;   double xielv=0,txielv; struct dian    {     long long   int  x,y;    }d[10005],ans[10005];int cmp(dian a,dian b){    if(a.x<b.x)        return 1;    return 0;}int main(){   scanf("%lld",&n);   for(i=0;i<n;i++)   {    scanf("%lld%lld",&d[i].x,&d[i].y);    shunxu[i]=d[i].x;   }   sort(d,d+n,cmp);   temp=n-1;   for(i=0;i<temp;i++)   {      j=i+1;            if(d[j].y<=d[i].y)                continue;            txielv=(double(d[j].y-d[i].y))/(double(d[j].x-d[i].x));           if(txielv>xielv)           {               xielv=txielv;               ans[0].x=d[i].x;               ans[0].y=d[j].x;               ansnum=1;           }           else if(txielv==xielv)           {               ans[ansnum].x=d[i].x;               ans[ansnum].y=d[j].x;           }   }     for(i=0;i<ansnum;i++)     {         for(j=0;j<n;j++)         {             if(shunxu[j]==ans[i].x)                ax=j+1;             else if(shunxu[j]==ans[i].y)                ay=j+1;         }         printf("%lld %lld\n",ax,ay);     }    return 0;}

只是把一个循环改成了i+1;因为按x排序,所以只要和后一个比较

如果早知道这个规律根本不用那么多行,还是太年轻



原创粉丝点击