题目大意:
题目链接:https://jzoj.net/senior/#main/show/4235
给出一个数列,求这个数列的尽量靠前的三个数字保证它们能够组成三角形。
思路:
n
≤
1
0
5
n\leq 10^5
n≤105,几乎是不可能做的。
正常来说,为了满足尽量靠前,所以会从前往后枚举。所以为了卡掉这种方法,它肯定要让前面尽量更多的数字满足无法组成三角形。但是题目说
x
≤
1
0
9
x\leq 10^9
x≤109,也就是说,既要满足不组成三角形,数列中任意数字有不能超过
1
0
9
10^9
109。
那么设前两个数字是
a
1
a_1
a1和
a
2
a_2
a2,那么接下来的数字为了不能组成三角形又要尽量小,所以肯定是
a
3
=
a
1
+
a
2
a_3=a_1+a_2
a3=a1+a2,接下来
a
4
=
a
2
+
a
3
a_4=a_2+a_3
a4=a2+a3。
我们发现,这是斐波那契数列,而
F
i
b
[
50
]
Fib[50]
Fib[50]已经超过
1
0
9
10^9
109,所以答案一定在前
50
50
50个数字内。所以
m
n
3
mn^3
mn3的复杂度是可过的。
代码:
#include <cstdio>
#include <algorithm>
using namespace std;
int n,m,x,y,a[100010];
bool ok;
void print(int x,int y,int z)
{
printf("%d ",min(x,min(y,z)));
printf("%d ",x+y+z-max(x,max(y,z))-min(x,min(y,z)));
printf("%d\n",max(x,max(y,z)));
}
int main()
{
scanf("%d",&n);
for (int i=1;i<=n;i++)
scanf("%d",&a[i]);
scanf("%d",&m);
while (m--)
{
scanf("%d",&x);
if (x==1) //修改操作
{
scanf("%d%d",&x,&y);
a[x]=y;
}
else
{
ok=1;
for (int i=1;i<=n&&ok;i++)
for (int j=1;j<i&&ok;j++)
if (i!=j)
for (int k=1;k<j;k++)
if (i!=k&&k!=j&&a[i]+a[j]>a[k]&&abs(a[i]-a[j])<a[k]) //符合三角形性质
{
print(a[i],a[j],a[k]);
ok=0;
break;
}
if (ok) printf("-1 -1 -1\n");
}
}
return 0;
}