51Nod--1100-斜率最大
平面上有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
题解:
计算几何的经典题目 (学cv的很有必要掌握)
1, 因为题目中说 任意两个点的x轴不相同,所以说每两个点之间必定有斜率
2,这种情况下, 将 众点 按x轴 sort 之后, 发现: 斜率最大的线段只可能存在于两两相邻的点之间。
3, 多个相同的,需要一并输出,建立一个stack来存answer 即可。
#include <iostream> #include <cstdio> #include <cstring> #include <cstdlib> using namespace std; const int MAXN = 10000 + 5; int n, top, save[MAXN][2]; struct Node{ int x, y, idx; }nd[MAXN]; int cmp(const void *a, const void *b){ Node *aa = (Node *)a; Node *bb = (Node *)b; return (aa->x - bb->x); } double computeSlope(const Node &a, const Node &b){ return (1.0*(a.y - b.y)/(a.x - b.x)); } int main(){ freopen("in.txt", "r", stdin); int xx, yy; while(scanf("%d", &n) != EOF){ for(int i=0; i<n; ++i){ scanf("%d %d", &xx, &yy); nd[i].x = xx; nd[i].y = yy; nd[i].idx = i + 1; } qsort(nd, n, sizeof(nd[0]), cmp); top = 0; double tmp_slope, max_slope = -1000000.0; for(int i=1; i<n; ++i){ tmp_slope = computeSlope(nd[i], nd[i-1]); if(max_slope < tmp_slope){ max_slope = tmp_slope; top = 0; }else if(max_slope == tmp_slope){ top++; }else{ continue; } save[top][0] = nd[i-1].idx; save[top][1] = nd[i].idx; } for(int i=0; i<=top; ++i){ printf("%d %d ", save[i][0], save[i][1]); } } return 0; }