51Nod--1100-斜率最大
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\n", save[i][0], save[i][1]);}}return 0;
}