题目大意:
Fiugou想要在一个长度为N的序列A中找到不同位置的三个数,以这三个数为三边长来构成一个三角形。但是它希望在满足条件下,这三个数的位置尽量靠前。具体地,设这三个数的为Ai,Aj,Ak(i<j<k), Fiugou希望k尽量小;当k相等时,满足j尽量小;当k,j均相等时,满足i尽量小。
但是这个序列中的数可能会发生变化。所以Fiugou给出了M个操作,形式如下:
1 x y:将Ax改为y
2:查询最优的合法解,从小到大给出这三个数(而不是位置)。
对于10%的数据,
对于30%的数据,
对于50%的数据,
对于100%的数据,
对于100%的数据,
解题思路:
暴力枚举
我们发现不满足三角形三边定理的话
,那么最坏情况下就是
……这就是斐波那契数列,所以我们每个循环最多只需要枚举50遍,时间复杂度为O(能过)
#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
#define file(x) freopen(#x".in", "r", stdin), freopen(#x".out", "w", stdout)
using namespace std;
struct Result {
int f, s, t;
};
int n, m;
int a[100005];
inline signed read() {
int f = 0, flag = 1; char c = getchar();
while (isdigit(c) == 0) flag = (c == '-') ? -1 : 1, c = getchar();
while (isdigit(c) != 0) f = (f<<1) + (f<<3) + c - 48, c = getchar();
return flag * f;
}
Result find() {
for (int i = 3; i <= min(50, n); ++i)
for (int j = 2; j < i; ++j)
for (int k = 1; k < j; ++k) {
int maxa = max(a[k], max(a[i], a[j]));
int mina = min(a[k], min(a[i], a[j]));
int mida = maxa == a[k] ? (mina == a[i] ? a[j] : a[i]) : (maxa == a[i] ? max(a[k], a[j]) : (max(a[i], a[k])));
if (mina + mida > maxa && maxa - mida < mina)
return (Result){mina, mida, maxa};
}
return (Result){-1, -1, -1};
}
int main() {
n = read();
for (int i = 1; i <= n; ++i)
a[i] = read();
m = read();
for (int i = 1; i <= m; ++i) {
if (read() == 2) {
Result x = find();
printf("%d %d %d\n", x.f, x.s, x.t);
} else
a[read()] = read();
}
}