处女座的签到题

链接: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

输入

复制
1
4 3
1 1
0 0
0 1
0 -1

输出

复制
0.50

说明

样例中一共能构成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);
    }
  }
}

 

posted @ 2019-01-24 19:49  知道了呀~  阅读(244)  评论(0编辑  收藏  举报