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;
}

浙公网安备 33010602011771号