- 题目描述
平面上有n个点,问:平面上所有三角形面积第k大的三角形的面积是多少?- 输入描述:
第一行T,表示样例的个数。
对于每一组样例,第一行两个整数n和k,
接下来n行,每行两个整数x,y表示点的坐标
T<=80
3<=n<=100
-109<=x,y<=109
对于每一组样例,保证任意两点不重合,且能构成的三角形的个数不小于k- 输出描述:
对于每一组样例,输出第k大三角形的面积,精确到小数点后两位(四舍五入)。- 输入
1
4 3
1 1
0 0
0 1
0 -1- 输出
0.50- 说明:样例中一共能构成3个三角形,面积分别为0.5,0.5,和1,面积第3大的为0.5
对于三角形的面积,枚举所有的情况,用向量积算出每一个三角形面积*2,然后我们用STL中的nth_element();找到第k大的三角形.
- nth_element()
nth_element(a+1,a+k,a+n+1);表示在[1,n+1)下标区间内将第k小的数放在下标为k的位置上.
nth_element(a+1,a+k,a+1+n,cmp);表示在[1,n+1)下标区间内将第k大的数放在下标为k的位置上.(cmp函数在下面代码中)
#include<cstdio>
#include<iostream>
#include<cstdlib>
#include<cstring>
#include<algorithm>
#include<vector>
#include<cmath>
using namespace std;
typedef long long LL;
const int Max_n=105;
LL x[Max_n],y[Max_n],ans[10000005];
LL Area(int i,int j,int k){//这里注意返回值
LL ans=abs((x[j]-x[i])*(y[k]-y[j])-(y[j]-y[i])*(x[k]-x[j]));
return ans;//三角形面积*2
}
bool cmp(LL a,LL b){
return a>b;
}
int main(){
int t;
scanf("%d",&t);
while(t--){
int n,k,num=1;
scanf("%d%d",&n,&k);
for(int i=1;i<=n;i++)
scanf("%lld%lld",&x[i],&y[i]);
for(int i=1;i<=n;i++){
for(int j=i+1;j<=n;j++){
for(int k=j+1;k<=n;k++){
//样例解释只有三个三角形(实际是4个)
if(Area(i,j,k)==0) continue;
ans[num++]=Area(i,j,k);
}
}
}
nth_element(ans+1,ans+k,ans+num,cmp);
if(ans[k]&1) printf("%lld.50\n",ans[k]/2);
else printf("%lld.00\n",ans[k]/2);
}
return 0;
}