题目
Description
Fiugou想要在一个长度为N的序列A中找到不同位置的三个数,以这三个数为三边长来构成一个三角形。但是它希望在满足条件下,这三个数的位置尽量靠前。具体地,设这三个数的为Ai,Aj,Ak(i<j<k), Fiugou希望k尽量小;当k相等时,满足j尽量小;当k,j均相等时,满足i尽量小。
但是这个序列中的数可能会发生变化。所以Fiugou给出了M个操作,形式如下:
1 x y:将Ax改为y
2:查询最优的合法解,从小到大给出这三个数(而不是位置)。
但是这个序列中的数可能会发生变化。所以Fiugou给出了M个操作,形式如下:
1 x y:将Ax改为y
2:查询最优的合法解,从小到大给出这三个数(而不是位置)。
Input
第一行一个整数N,代表序列的长度。
第二行有N个整数,代表初始序列。
第三行一个整数M,代表操作的个数。
接下来M行操作,两种操作格式如上所述。
第二行有N个整数,代表初始序列。
第三行一个整数M,代表操作的个数。
接下来M行操作,两种操作格式如上所述。
Output
共M行,每行三个数,从小到大给出。如果不存在,输出-1 -1 -1。
Sample Input
6
7 1 3 4 5 1
3
2
1 3 5
2
Sample Output
3 5 7
4 5 7
Data Constraint
对于10%的数据, N<=10, M<=5
对于30%的数据, N<=100, M<=25
对于50%的数据, N<=1000, M<=1000
对于100%的数据, N<=100000, M<=1000
对于100%的数据, 0<=Ai<=10^9, 1<=x<=N, 0<=y<=10^9
对于30%的数据, N<=100, M<=25
对于50%的数据, N<=1000, M<=1000
对于100%的数据, N<=100000, M<=1000
对于100%的数据, 0<=Ai<=10^9, 1<=x<=N, 0<=y<=10^9
分析
-
首先,我们肯定知道如何用暴力的方法做
-
O(n^3) 但是数据太水。。。能过
- 正解:其实不能组成三角形的情况也就是一个feb数列
- 我们可以得知feb 到了第五十位是很大的
- 也就是说在这个数列中,如果一旦超过五十个后面将视为无效
- 因为如果在前50个数中每个数都不一样 那么一定能组成一个最小的
- 这道题主要是想卡-1-1-1的情况,所以如果我们超出50个数之后还有的话那么已经超出数据规模了
代码
1 #include<iostream> 2 using namespace std; 3 int a[100001]; 4 int main () 5 { 6 ios::sync_with_stdio(false); 7 int n,m; 8 cin>>n; 9 for (int i=1;i<=n;i++) 10 cin>>a[i]; 11 cin>>m; 12 bool flag=0; 13 for (int i=1,x,y,z,b=-1,c=-1,d=-1;i<=m;i++) 14 { 15 cin>>x; 16 if (x==2) 17 { 18 flag=1; 19 int bk=0; 20 for (int ii=3;ii<=min(n,50);ii++) 21 { 22 if (bk==1) 23 break; 24 for (int j=1;j<=ii-1;j++) 25 { 26 if (bk==1) 27 break; 28 for (int k=1;k<=j-1;k++) 29 if (a[ii]+a[j]>a[k]&&a[ii]+a[k]>a[j]&&a[j]+a[k]>a[ii]) 30 { 31 b=min(a[ii],min(a[j],a[k])); 32 if (b==a[ii]) 33 { 34 c=min(a[j],a[k]); 35 if (c==a[j]) 36 d=a[k]; 37 else 38 d=a[j]; 39 } 40 if (b==a[j]) 41 { 42 c=min(a[ii],a[k]); 43 if (c==a[ii]) 44 d=a[k]; 45 else 46 d=a[ii]; 47 } 48 if (b==a[k]) 49 { 50 c=min(a[ii],a[j]); 51 if (c==a[ii]) 52 d=a[j]; 53 else 54 d=a[ii]; 55 } 56 bk=1; 57 break; 58 } 59 } 60 } 61 cout<<b<<" "<<c<<" "<<d<<endl; 62 } 63 else 64 { 65 flag=0; 66 cin>>y>>z; 67 a[y]=z; 68 } 69 } 70 }