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:查询最优的合法解,从小到大给出这三个数(而不是位置)。
Input
第一行一个整数N,代表序列的长度。
第二行有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
Solution
我们发现其实做序列前50个数就可以了。因为如果我们要使一个序列中任意3个数不能组成三角形的长度要尽量长的话,那么最坏的情况就是,第一个数是0,第二个数是1,第三个数是1,第四个数是2,第五个数是3,以此类推......因为若一个数小于前面两个数之和,那么这个数和前面两个数一定能构成一个三角形,因为a的范围是小于10^9次方的,所以当这个序列的长度大于50时,这个数就大于了10^9所以我们只要找前50个数就一定能找出3个数使得它们能够成三角形。
Code
#include<cstdio>
#include<cstring>
#include<algorithm>
#define N 100010
using namespace std;
int n,m,k,x,y,a1,a2,a3,a[N],ans[4],bz;
int pd(int x,int y,int z){
int m1=min(x,min(y,z)),m2;
if(m1==x) m2=y<z?y:z;
else if(m1==y) m2=x<z?x:z;
else if(m1==z) m2=x<y?x:y;
if(m1+m2>x+y+z-m1-m2) return 1;
return 0;
}
int main(){
freopen("sequence.in","r",stdin);
freopen("sequence.out","w",stdout);
scanf("%d",&n);
for(int i=1;i<=n;i++) scanf("%d",&a[i]);
scanf("%d",&m);
while(m--){
scanf("%d",&k);
if(k==1){
scanf("%d%d",&x,&y);
a[x]=y;
}
else{
ans[1]=-1;ans[2]=-1;ans[3]=-1;
for(int i=3;i<=47;i++){
for(int j=1;j<=i-1;j++){
for(int k=1;k<=j-1;k++){
if(pd(a[i],a[j],a[k])){
ans[1]=a[i];ans[2]=a[j];ans[3]=a[k];
a1=i;a2=j;a3=k;
break;
}
}
if(ans[1]!=-1) break;
}
if(ans[1]!=-1) break;
}
sort(ans+1,ans+4);
printf("%d %d %d\n",ans[1],ans[2],ans[3]);
}
}
return 0;
}
作者:zsjzliziyang
QQ:1634151125
转载及修改请注明
本文地址:https://blog.csdn.net/zsjzliziyang/article/details/86683520