51nod 1100 斜率最大
2017-08-05 00:16
190 查看
平面上有N个点,任意2个点确定一条直线,求出所有这些直线中,斜率最大的那条直线所通过的两个点。
(点的编号为1-N,如果有多条直线斜率相等,则输出所有结果,按照点的X轴坐标排序,正序输出。数据中所有点的X轴坐标均不相等,且点坐标为随机。)
Input
Output
Input示例
Output示例
学校老司机建议写下自己当时思路,有利于以后复习,一开始还没怎么在意,今天看两周前的题目居然忘了怎么做,吓得我马上开了个博客,主要是学习过程,非大神,看官们轻喷
首先看了这道题第一感觉是暴力(菜鸡只能暴力), 最暴力的方法就是两个for循环,比较斜率,估计会爆所以跳过
1 :将点首先按x坐标排序,有利于保存答案和优化
2 :计算过程保存一个最高y点,在x增大的情况下y如果一样大,肯定斜率更低。
3 :保存的话用数组保存两个点的x值,因为题目x都不相同,题目要求输出原来的数组的顺序点,所以开个数组保存原顺序,然后算出答案从中匹配
附上代码:
然后发现别人的代码都是20ms以内
发现有个数学规律,排序后斜率最大的两个点肯定是相邻的,用反证法更容易验证,那我写那么多干吗唉
附上代码:
只是把一个循环改成了i+1;因为按x排序,所以只要和后一个比较
如果早知道这个规律根本不用那么多行,还是太年轻
(点的编号为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 1100 斜率最大
- 51nod 1100:斜率最大
- 51nod_1100_斜率最大
- 51NOD 1100 斜率最大
- 51nod 1100 斜率最大
- 51Nod-1100-斜率最大
- 51Nod 1100 斜率最大
- 51nod 1100 斜率最大
- 51nod 1100 斜率最大
- 51Nod-1100 斜率最大
- 【51nod 1100】斜率最大
- 51nod 1100 斜率最大
- 51nod-1100 斜率最大
- 51Nod 斜率最大(拉勾专业算法能力测评)
- 51Nod 斜率最大
- 51Nod-斜率最大
- 1100 斜率最大(找规律)
- 51Nod 斜率最大
- 51nod oj 1100 斜率最大
- 【51NOD】斜率最大