【校内模拟】三角形

题目链接

三角形

时限:\(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\%\)的数据,\(1\leq n\leq 10^3\)

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

对于另外\(0\%\)的数据,\(1\leq 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\n",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\n",ans);
				break;
			}
		if(!flag) puts("No Answer!");
	}
	return 0;
}

然而由于数据是随机的

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

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

posted @ 2018-11-05 17:09  yjk  阅读(273)  评论(0编辑  收藏  举报