• 处女座的签到题


    链接: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
    本题的坑:
    1.数据过大,不能用double存,叉积返回整数,要除2之前判断一下奇偶性,补一下小数点后缀就好了
    2.叉积求三角形面积,海伦公式开根号精度不能保证
    3.暴力三重循环求所有三角形,筛去同一直线上的三个点的组合。同一直线上的叉积为0。
    4.不能用sort排序,复杂度为O(nlogn),很可能爆时间,用快速排序求第k大或者调用函数nth_element,复杂度O(n)
    #include<stdio.h>
    #include<iostream>
    #include<algorithm>
    #include<cstring>
    #include<math.h>
    #include<set>
    #define ll long long
    #define inf 0x3f3f3f3f
    using namespace std;
    struct node
    {
        ll x;
        ll y;
    };
    node p[105];
    ll ans[1000005];
    ll s(node p1,node p2,node p3)
    {
        ll chaji=(p2.x-p1.x)*(p3.y-p1.y)-(p3.x-p1.x)*(p2.y-p1.y);
        return abs(chaji);
    }
    int main()
    {
        int t;
        scanf("%d",&t);
        int n,k;
        while(t--)
        {
            scanf("%d%d",&n,&k);//求第k大
            for(int i=1;i<=n;i++)
            {
                scanf("%lld%lld",&p[i].x,&p[i].y);
            }
            int x=0;
            for(int i=1;i<=n;i++)
                for(int j=i+1;j<=n;j++)
                    for(int k=j+1;k<=n;k++)
                    {
                        ll temp=s(p[i],p[j],p[k]);
                        if(temp) ans[x++]=temp;
                    }
            nth_element(ans,ans+x-k,ans+x);///排(x+1-k)小
            if(ans[x-k]%2==1)
                printf("%lld.50
    ",ans[x-k]/2);
            else
                printf("%lld.00
    ",ans[x-k]/2);
        }
        return 0;
    }
    //用人话讲,排好第k+1小的元素的下标为k
    //用鬼话讲,从第0个排,第k个的放在下标为k的位置
    //nth_element(ans,ans+k,ans+x);
    /*人话与鬼话
    数组ans里,总元素个数为x,人话第a大和人话第b小的关系。
    假设x=10,元素分别为1,2,3,4,5,6,7,8,9,10。
    下标分别是0,1,2,3,4,5,6,7,8,9。
    设a=3,求b等于多少?
    人话的第三大就是8,放在下标为7的空间里。
    转化成人话的就是第b小,则元素8是第8小,
    ∴人话的大小转化是: b=x+1-a
    然而写入函数找人话的第b小是计算机鬼话从0开始排,放在b-1下标里
    ∴函数中间那个参数表示,人话的第b大放在下标为b-1的下标里
    */
     
  • 相关阅读:
    201521123038 《Java程序设计》 第五周学习总结
    201521123020 《Java程序设计》第4周学习总结
    201521123020 《Java程序设计》第3周学习总结
    201521123020《Java程序设计》第2周学习总结
    Java第十二周学习总结
    Java第十一周学习总结
    Java第十周学习总结
    Java第九周学习总结
    Java第八周学习总结
    Java第七周学习总结
  • 原文地址:https://www.cnblogs.com/shoulinniao/p/10322399.html
Copyright © 2020-2023  润新知