CF2111D

发现 \(a_i\) 的最后两位对答案没有任何影响,因此我们只需考虑 \(a_i\) 所在楼层。按照所在楼层从低到高对 \(a\) 排序。
\(b_i=\lfloor \frac{a_i}{100} \rfloor\)对于每两节课之间,我们要选 \(x_1,x_2,\cdots,x_n\)\(y_1,y_2,\cdots,y_n\) 使 $\sum_{i=1}^n \left| x_i-y_i\right| $ 最大。不妨让 \(x_1=y_n=b_1,x_2=y_{n-1}=b_2,\cdots,x_{\lfloor \frac{n}{2} \rfloor}=y_{\lfloor \frac{n}{2} \rfloor+1}=b_{\lfloor \frac{n}{2} \rfloor}\)\(x_n=y_1=b_m,x_{n-1}=y_2=b_m-1,\cdots,x_{\lfloor \frac{n}{2} \rfloor+1}=y_{\lfloor \frac{n}{2} \rfloor}=b_{m-\lfloor \frac{n}{2} \rfloor+1}\),这样赋值就可以保证拆绝对值后,是最大的 \(\lfloor \frac{n}{2} \rfloor\) 个数减去最小的 \(\lfloor \frac{n}{2} \rfloor\) 个数再乘 \(2\),答案已经最大化了。

实现时观察到具有对称性,因此知道当前的教室的排名就可以知道下一间教室的排名。时间复杂度 \(O(\sum(m\log m+n))\)

#include<iostream>
#include<cstdio>
#include<algorithm>
#define N 500010
using namespace std;
bool cmp(int x,int y){
    return x/100<y/100;
}
int n,m,a[N];
void solve(){
    cin>>n>>m;
    for(int i=1;i<=m;i++)
        cin>>a[i];
    sort(a+1,a+m+1,cmp);
    for(int i=1;i<=n/2;i++){
        for(int j=1;j<=6;j++)
            if(j%2)
                cout<<a[i]<<' ';
            else
                cout<<a[m-i+1]<<' ';
        cout<<'\n';
    }
    for(int i=n/2+1,k=m;i<=n;i++,k--){
        for(int j=1;j<=6;j++)
            if(j%2)
                cout<<a[k]<<' ';
            else
                cout<<a[m-k+1]<<' ';
        cout<<'\n';
    }
    return;
}
int main(){
    int T;
    cin>>T;
    while(T--)solve();
    return 0;
}
posted @ 2025-09-12 08:12  FormulaOne  阅读(9)  评论(0)    收藏  举报