• 【校内模拟】三角形


    题目链接

    三角形

    时限:(100ms)    空间:(512MB)

    【题目背景】

    【题目描述】

    (n)个木棍,现在知道了每个木棍的长度,要从中挑出三个木棍组成一个三角形,

    如何挑选木棍,使得组成的三角形的面积最大

    由于出题人不会做

    由于上面的要求过于毒瘤,

    良心的出题人将题面改为了求一个方案使得三角形的周长最大

    输出这个三角形的三边长和面积

    【输入输出格式】

    输入格式

    第一行一个整数(T),表示数据组数

    对于每组数据

    第一行一个整数(n),表示木棍的个数

    第二行(n)个整数,表示这(n)个木棍的长度

    输出格式

    对于T组数据

    若不能构成三角形,输出"(!No~ Answer!)"

    否则

    第一行从小到大输出三个整数(a,b,c),表示周长最大的三角形的三边长

    第二行输出一个数,表示三角形的面积,只需要精确到整数

    【输入输出样例】

    输入样例

    输入样例#1:

    1
    5
    1 2 3 4 5
    

    输入样例#2:

    1
    5
    1 1 2 3 5
    

    输出样例

    输出样例#1:

    3 4 5
    6
    

    输出样例#2:

    No Answer!
    

    【数据范围】

    对于前(50\%)的数据,(1leq nleq 10^3)

    对于前(100\%)的数据,(1leq Tleq 10,1leq nleq 10^5,a_i leq 10^{9})

    对于另外(0\%)的数据,(1leq T leq 10^{10^{10^{10}}}!, 1 leq n leq 10^{10^{10^{10^{10^{10}}}}}),(a_i)在复数系范围内

    海伦公式:(S=sqrt {p(p-a)(p-b)(p-c)})

    (mathcal{solution})

    显然,我们可以贪心地不断找最长的三条边,如果可以构成三角形,就输出答案

    (sort)一遍复杂度是(O(T*nlogn))的,期望得分(50)

    然而我们发现实际上如果(n>50),那么一定会存在三角形

    因为(a_i)的范围比较小,如果(50)个边仍无法构成三角形的话

    我们考虑边的大小递增

    (1、2)个边长最小为(1),那么第(3)个边最小为(1+1=2)

    (4)个边最小为(1+2=3),第(5)个边最小为(2+3=5)……

    显然第(50)条边为(fib_{50}),它是远大于(a_i)的范围的

    所以当(n geq 50)时,

    所以可以用(STL)(nth\_element)将前(50)大的搞到一块儿,

    将这(50)(sort)一边贪心地取即可

    求面积直接套公式即可,记得要用(double)

    (mathcal{std})

    #include<algorithm>
    #include<iostream>
    #include<cstring>
    #include<cstdio>
    #include<cmath>
    using namespace std;
    #define N 10000010
    int T,n,a[N];
    const int ch_top=5e8+3;
    char ch[ch_top],*now_r=ch-1;
    inline int read(){
        while(*++now_r<'0');
        register int x=*now_r-'0';
        while(*++now_r>='0')x=(x<<3)+(x<<1)+*now_r-'0';
        return x;
    }
    int main()
    {
    	fread(ch,1,ch_top,stdin);
    	T=read();
    	while(T--){
    		n=read();
    		for(int i=1;i<=n;++i)
    			a[i]=read();
    		if(n>50){
    			nth_element(a+1,a+1+n-50,a+1+n);
    			sort(a+1+n-50,a+1+n);
    		}
    		else sort(a+1,a+1+n);
    		bool flag=0;
    		long double x,y,z,p,ans;
    		for(int i=n-2;i>=1;--i)
    			if(a[i]+a[i+1]>a[i+2]){
    				flag=1;
    				printf("%d %d %d
    ",a[i],a[i+1],a[i+2]);
    				x=a[i],y=a[i+1],z=a[i+2];
    				p=(x+y+z)/2.0;
    				ans=sqrtl(p*(p-a[i])*(p-a[i+1])*(p-a[i+2]));
    				printf("%.0Lf
    ",ans);
    				break;
    			}
    		if(!flag) puts("No Answer!");
    	}
    	return 0;
    }
    

    然而由于数据是随机的

    直接找前三个最大数就可以过

    不管不管不是我的锅嘤嘤嘤

  • 相关阅读:
    mkdosfs 安装
    块设备驱动程序-内存盘
    usb驱动程序小结(六)
    usb的hid鼠标键盘报告描述符(五)
    usb输入子系统写程序(三)
    usb输入子系统键盘(四)
    usb描述符简述(二)
    linux usb总线驱动(一)
    linux 触摸屏驱动
    lcd驱动框架
  • 原文地址:https://www.cnblogs.com/yjkhhh/p/9892799.html
Copyright © 2020-2023  润新知