2023 杭电多校(“钉耙编程”中国大学生算法设计超级联赛3)T9 题解

  • Post author:
  • Post category:其他


抢了个一血。不懂啊,这么傻逼的题居然没有人在



52

min

52 \min






52




min





内切(我如果小细节不写挂就十分钟切了)。



题目描述

给你若干个三元组



(

a

i

,

b

i

,

c

i

)

(a_i,b_i,c_i)






(



a










i


















,





b










i


















,





c










i


















)









(

a

i

,

b

i

,

c

i

)

(a_i’,b_i’,c_i’)






(



a










i





























,





b










i





























,





c










i





























)





你可以从



(

a

i

,

b

i

,

c

i

)

(a_i,b_i,c_i)






(



a










i


















,





b










i


















,





c










i


















)









(

a

i

,

b

i

,

c

i

)

(a_i’,b_i’,c_i’)






(



a










i





























,





b










i





























,





c










i





























)





中选择一个三元组作为第



i

i






i





个三元组(



a

i

a

i

,

b

i

b

i

,

c

i

c

i

a_i’ \ge a_i,b_i’ \ge b_i,c_i’ \ge c_i







a










i









































a










i


















,





b










i









































b










i


















,





c










i









































c










i





















)。

设你最后选择的三元组是



(

A

i

,

B

i

,

C

i

)

(A_i,B_i,C_i)






(



A










i


















,





B










i


















,





C










i


















)





那么这种方案的权值就是



max

(

max

A

i

min

A

i

,

max

B

i

min

B

i

,

max

C

i

min

C

i

)

\max(\max A_i-\min A_i,\max B_i – \min B_i,\max C_i- \min C_i)






max


(


max





A










i





























min





A










i


















,




max





B










i





























min





B










i


















,




max





C










i





























min





C










i


















)





你需要找出一种方案,使得权值最小,并输出最小权值。



思路

看到最大值最小,直接二分。

考虑如何



c

h

e

c

k

\rm check







check






我们把



(

a

i

,

b

i

,

c

i

)

(a_i,b_i,c_i)






(



a










i


















,





b










i


















,





c










i


















)









(

a

i

,

b

i

,

c

i

)

(a_i’,b_i’,c_i’)






(



a










i





























,





b










i





























,





c










i





























)





并成一个六元组



(

a

i

,

b

i

,

c

i

,

a

i

,

b

i

,

c

i

)

(a_i,b_i,c_i,a_i’,b_i’,c_i’)






(



a










i


















,





b










i


















,





c










i


















,





a










i





























,





b










i





























,





c










i





























)





,先钦定所有三元组都选



(

a

i

,

b

i

,

c

i

)

(a_i,b_i,c_i)






(



a










i


















,





b










i


















,





c










i


















)





搞三个数组:



x

,

y

,

z

x,y,z






x


,




y


,




z





,分别表示这个六元组按



a

i

a_i







a










i





















排序,按



b

i

b_i







b










i





















排序,按



c

i

c_i







c










i





















排序后的结果。

不难发现需要换成



(

a

i

,

b

i

,

c

i

)

(a_i’,b_i’,c_i’)






(



a










i





























,





b










i





























,





c










i





























)





的三元组一定是



x

,

y

,

z

x,y,z






x


,




y


,




z





的一段前缀。

三个指针扫一遍即可。

注意需要判断前面三元组换了之后还是不满足条件的情况。

时间复杂度



O

(

n

log

n

)

\mathcal O(n \log n)






O


(


n




lo

g





n


)







代码

//A tree without skin will surely die.
//A man without face is invincible.
#include<bits/stdc++.h>
using namespace std;
#define int long long
#define sqr(x) ((x)*(x))
#define all(x) (x).begin(),(x).end()
#define Tim ((double)clock()/CLOCKS_PER_SEC)
#define mid ((l+r)>>1)
#define lowbit(x) (x&-x)
int const N=1e5+10;
int n,nwx,nwy,nwz,ix,iy,iz,qza,qzb,qzc;
struct node{int a,b,c,d,e,f;}a[N],b[N],c[N];
void push(node x){
    nwx=max(nwx,x.d),nwy=max(nwy,x.e),nwz=max(nwz,x.f);
    qza=min(qza,x.d),qzb=min(qzb,x.e),qzc=min(qzc,x.f);
}
bool check(int V){
    nwx=a[n].a,nwy=b[n].b,nwz=c[n].c,ix=1,iy=1,iz=1,qza=1e9,qzb=1e9,qzc=1e9;
    while (1){
        if (nwx-a[ix].a<=V && nwy-b[iy].b<=V && nwz-c[iz].c<=V && nwx-qza<=V && nwy-qzb<=V && nwz-qzc<=V) return 1;
        while (ix<=n && nwx-a[ix].a>V){push(a[ix]),++ix;if (nwx-qza>V || nwy-qzb>V || nwz-qzc>V) return 0;}
        while (iy<=n && nwy-b[iy].b>V){push(b[iy]),++iy;if (nwx-qza>V || nwy-qzb>V || nwz-qzc>V) return 0;}
        while (iz<=n && nwz-c[iz].c>V){push(c[iz]),++iz;if (nwx-qza>V || nwy-qzb>V || nwz-qzc>V) return 0;}
        if (nwx-qza>V || nwy-qzb>V || nwz-qzc>V) return 0;
    }
    return 1;
}
void solve(){
    cin>>n;
    for (int i=1;i<=n;++i) cin>>a[i].a>>a[i].b>>a[i].c>>a[i].d>>a[i].e>>a[i].f;
    for (int i=1;i<=n;++i) b[i]=a[i],c[i]=a[i];
    sort(a+1,a+n+1,[](node x,node y){return x.a<y.a;});
    sort(b+1,b+n+1,[](node x,node y){return x.b<y.b;});
    sort(c+1,c+n+1,[](node x,node y){return x.c<y.c;});
    int l=0,r=1e9;
    while (l<r)
        if (check(mid)) r=mid;
        else l=mid+1;
    cout<<l<<'\n';
}
signed main(){
    ios::sync_with_stdio(false);
    cin.tie(0),cout.tie(0);
    int t=1;
    cin>>t;
    while (t--) solve();
    return 0;
}



版权声明:本文为yuzhouzli原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。