处女座的签到题
链接:https://ac.nowcoder.com/acm/contest/327/A
来源:牛客网
题目描述
平面上有n个点,问:平面上所有三角形面积第k大的三角形的面积是多少?
输入描述:
第一行T,表示样例的个数。
对于每一组样例,第一行两个整数n和k,
接下来n行,每行两个整数x,y表示点的坐标
T<=80
3<=n<=100
-109<=x,y<=109
对于每一组样例,保证任意两点不重合,且能构成的三角形的个数不小于k
输出描述:
对于每一组样例,输出第k大三角形的面积,精确到小数点后两位(四舍五入)。
示例1
说明
样例中一共能构成3个三角形,面积分别为0.5,0.5,和1,面积第3大的为0.5
PS:nth_elemet作为stl类的一个求第k大的数,据说平均复杂度是o(n);
nth_element(a+1,a+k,a+1+n),从a[1]到a[n]中找第k小的数;
如果找第k大,和sort一样
bool cmp(int a,int b)
{
return a>b;
}
nth_element(a+1,a+k,a+1+n,cmp);
注意:nth_element()函数不过将第n大的数排好了位置,并不返回值。
#include<iostream> #include<stdio.h> #include<algorithm> #define ll long long using namespace std; struct node { ll x; ll y; }xy[1000]; ll area[10000000]; int main() { int t; ll s; cin >> t; while (t--) { int t = 0; int n, k; cin >> n >> k; for (int i = 1; i <= n; i++) { cin >> xy[i].x >> xy[i].y; } for (int i = 1; i <= n - 2; i++) { for (int j = i + 1; j <= n - 1; j++) { for (int k = j + 1; k <= n; k++) { ll x1 = xy[i].x; ll y1 = xy[i].y; ll x2 = xy[j].x; ll y2 = xy[j].y; ll x3 = xy[k].x; ll y3 = xy[k].y; s = (x1*y2 + x2 * y3 + x3 * y1 - x1 * y3 - x2 * y1 - x3 * y2);//向量叉乘 if (s<0) { s = -s; } if (s>0) { area[t++] = s; } } } } nth_element(area, area + t - k, area + t); if (area[t - k] & 1) { printf("%lld.50\n", area[t - k] / 2); } else { printf("%lld.00\n", area[t - k] / 2); } } }
等风起的那一天,我已准备好一切