看守题解
看守题解
此题是这一题的简化版,
这道题看上去很难,曼哈顿距离之和就足以吓跑一大堆人,
但我们一看,D<=4,这就可以搞一套骚操作了,
我们试着去掉绝对值,会化成类似这样的式子:
\(x_{1}-y_{1}+y_{2}-x_{2}+y_{3}-x_{3}+x_{4}-y_{4}=(x_{1}-x_{2}-x_{3}+x_{4})-(y_{1}-y_{2}-y_{3}+y_{4})=(x_{1}-x_{2}-x_{3}+x_{4})+(-y_{1}+y_{2}+y_{3}-y_{4})\)
将其转化为二进制,0代表-,1代表+,
则最大曼哈顿距离为,相同0、1序列的最大差值,或与(1<<D)-1相补的0、1序列的最大和,
求出每种0、1序列的最大值和最小值,ans跟差值取max就行了
#include<bits/stdc++.h>
#define ll long long
#define re register
using namespace std;
const int N=1e6+6,inf=2e9;
struct xd{
int z[17];
}p[N];
int n,k,P,t[7],ans,minx,maxx;
inline int read(){
int T=0,F=1; char ch=getchar();
while(ch<'0'||ch>'9'){if(ch=='-') F=-1; ch=getchar();}
while(ch>='0'&&ch<='9') T=(T<<3)+(T<<1)+(ch-48),ch=getchar();
return F*T;
}
int main(){
n=read(),k=read(),P=(1<<k);
for(re int i=1;i<=n;++i){
for(int j=0;j<k;++j) t[j]=read();
for(re int j=0;j<P;++j){
for(int o=0;o<k;++o){
if(j&(1<<o)) p[i].z[j]+=t[o];
else p[i].z[j]-=t[o];
}
}
}
for(int i=0;i<P;++i){
minx=inf,maxx=-inf;
for(re int j=1;j<=n;++j) minx=min(minx,p[j].z[i]),maxx=max(maxx,p[j].z[i]);
ans=max(ans,maxx-minx);
}
printf("%d\n",ans);
return 0;
}