您的位置:首页 > 其它

51nod 1100 斜率最大

2017-08-05 00:16 190 查看
平面上有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示例
5
1 2
6 8
4 4
5 4
2 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排序,所以只要和后一个比较

如果早知道这个规律根本不用那么多行,还是太年轻
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  51nod ACM 计算几何