【51nod 1100】斜率最大

Description

平面上有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

证明最优解一定是在相邻两个点之间。

然后顺便感慨一下,隔壁O(n2)的暴力居然过了……目瞪口呆。

 1 #include<cstdio>
 2 #include<algorithm>
 3 #include<cstring>
 4 #include<cmath>
 5 using namespace std;
 6 struct node{int x,y,num;}a[10010];
 7 int n,cnt,t=2,ans[10010];
 8 double lv=-2e9;
 9 bool cmp(node a,node b){return a.x<b.x;}
10 int comp(double i,double j)
11 {
12     if(fabs(i-j)<1e-6)return 0;
13     if(i>j)return 1;
14     return -1;
15 }
16 double xl(int i,int j){return (double)(a[j].y-a[i].y)/(a[j].x-a[i].x);}
17 int main()
18 {
19     scanf("%d",&n);
20     for(int i=1;i<=n;i++)
21     {
22         scanf("%d%d",&a[i].x,&a[i].y);
23         a[i].num=i;
24     }
25     sort(a+1,a+n+1,cmp);
26     while(t<=n)
27     {
28         double f=xl(t-1,t);
29         if(comp(f,lv)>0){lv=f;cnt=0;ans[++cnt]=t-1;ans[++cnt]=t;}
30         else if(comp(f,lv)==0)ans[++cnt]=t;
31         t++;
32         while(t<=n&&comp(xl(t-2,t-1),xl(t-1,t))>0)t++;
33     }
34     for(int i=1;i<=cnt;i++)printf("%d ",a[ans[i]].num);
35     return 0;
36 }

时间: 2024-10-08 18:51:49

【51nod 1100】斜率最大的相关文章

51nod - 1100 斜率最大

题目链接:http://www.51nod.com/onlineJudge/questionCode.html#!problemId=1100 虽然这题数据有点小,但是做题嘛,总是要有追求的,不能什么都靠暴力. 随便画个图就可以看到,斜率最大的情况它们的横坐标一定是相邻的.于是,最后只要排个序就好了. 1 #include <bits/stdc++.h> 2 using namespace std; 3 const int maxn = 1e4 + 100; 4 struct st 5 { 6

51Nod P1100 斜率最大

传送门: https://www.51nod.com/onlineJudge/questionCode.html#!problemId=1100 由于2 <= N <= 10000, 所以不难想出一个O(n^2)的枚举算法,枚举两个点的坐标.不断更新最大斜率的值,用一个结构体数组来记录两个点,每次更新的时候将数组的下标重置为1. #include <cstdio> #include <cstring> #include <cmath> #include &l

51Nod - 1107 斜率小于0的连线数量

二维平面上N个点之间共有C(n,2)条连线.求这C(n,2)条线中斜率小于0的线的数量. 二维平面上的一个点,根据对应的X Y坐标可以表示为(X,Y).例如:(2,3) (3,4) (1,5) (4,6),其中(1,5)同(2,3)(3,4)的连线斜率 < 0,因此斜率小于0的连线数量为2. Input第1行:1个数N,N为点的数量(0 <= N <= 50000) 第2 - N + 1行:N个点的坐标,坐标为整数.(0 <= Xii , Yii <= 10^9)Output

【51NOD】斜率最大

[题解]通过画图易得结论:最大斜率一定出现在相邻两点之间. #include<cstdio> #include<algorithm> #include<cstring> using namespace std; const int maxn=10010; const double eps=1e-6; struct cyc{int x,y,ord;}a[maxn]; int b[maxn],n; bool cmp(cyc a,cyc b) {return a.x<b

51NOD——N 1107 斜率小于0的连线数量

https://www.51nod.com/onlineJudge/questionCode.html#!problemId=1107 基准时间限制:1 秒 空间限制:131072 KB 分值: 40 难度:4级算法题  收藏  关注 二维平面上N个点之间共有C(n,2)条连线.求这C(n,2)条线中斜率小于0的线的数量. 二维平面上的一个点,根据对应的X Y坐标可以表示为(X,Y).例如:(2,3) (3,4) (1,5) (4,6),其中(1,5)同(2,3)(3,4)的连线斜率 < 0,因

51nod 1451 合法三角形 判斜率去重,时间复杂度O(n^2)

题目: 这题我WA了3次,那3次是用向量求角度去重算的,不知道错在哪了,不得不换思路. 第4次用斜率去重一次就过了. 注意:n定义成long long,不然求C(3,n)时会溢出. 代码: #include <bits\stdc++.h> using namespace std; typedef long long ll; struct point{ int x;int y; }a[2005]; map <long double,int>::iterator it; int mai

51nod 1107 1107 斜率小于0的连线数量

基准时间限制:1 秒 空间限制:131072 KB 分值: 40 难度:4级算法题 二维平面上N个点之间共有C(n,2)条连线.求这C(n,2)条线中斜率小于0的线的数量. 二维平面上的一个点,根据对应的X Y坐标可以表示为(X,Y).例如:(2,3) (3,4) (1,5) (4,6),其中(1,5)同(2,3)(3,4)的连线斜率 < 0,因此斜率小于0的连线数量为2. Input 第1行:1个数N,N为点的数量(0 <= N <= 50000) 第2 - N + 1行:N个点的坐标

n个点中求任意两点组成斜率的最大值

http://www.51nod.com/onlineJudge/questionCode.html#!problemId=1100 首先按x坐标排序,然后相邻的三个点A,B,C 组成的三条直线必然有K(AC)<max(K(A,B),K(B,C));(K是斜率) 所以斜率一定会在相邻的两点中产生,排序O(nlogn),更新最大值O(n). 1 #include <iostream> 2 #include <cstdio> 3 #include <cmath> 4

HDU 2829 Lawrence (斜率优化DP或四边形不等式优化DP)

题意:给定 n 个数,要你将其分成m + 1组,要求每组数必须是连续的而且要求得到的价值最小.一组数的价值定义为该组内任意两个数乘积之和,如果某组中仅有一个数,那么该组数的价值为0. 析:DP状态方程很容易想出来,dp[i][j] 表示前 j 个数分成 i 组.但是复杂度是三次方的,肯定会超时,就要对其进行优化. 有两种方式,一种是斜率对其进行优化,是一个很简单的斜率优化 dp[i][j] = min{dp[i-1][k] - w[k] + sum[k]*sum[k] - sum[k]*sum[