看守题解

看守题解

此题是这一题的简化版,
这道题看上去很难,曼哈顿距离之和就足以吓跑一大堆人,
但我们一看,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;
}
posted @ 2019-10-12 07:16  lsoi_ljk123  阅读(104)  评论(0编辑  收藏  举报