CWT大逃亡 escape题解

来源:互联网 发布:java的集成开发环境 编辑:程序博客网 时间:2024/06/09 14:55

题目描述

     因为害怕JY的瘴气,CWT开始的大逃亡,可是JY在穷追不舍。     慌不择路下,CWT跳进了一个K维空间,JY自然也追了进来。     这个K维空间里有N座城市,CWT和JY分别会选择一座城市休息,CWT当然希望自己所在的城市能离JY所在的城市最远,以减少瘴气对他的影响。     因为CWT是非常乐观的,他认为他和JY会分别在距离最远的那两座城市,所以他只想知道距离最远的两座城市的距离是多少。(这里的距离指曼哈顿距离,P1(x1,y1)与坐标P2(x2, y2)的曼哈顿距离为:|x1 - x2| + |y1 - y2|. )

输入

第一行包括两个整数n和k,表示有n个城市,是k维空间。
第二到第n+1行,每行k个整数,表示该城市的坐标。

输出

输出一行一个数表示最远的距离。

样例输入

4 4
0 0 0 0
1 2 3 4
4 3 2 1
-2 -1 0 1

样例输出

12

提示

【样例解释】

    从2号或者3号城市走到4号城市,距离均为12。

【数据范围】

    20%的数据满足n<=1000。     另外20%的数据满足k=1。     另外30%的数据满足k=2。    100%的数据满足,n<=50000,k<=7.    所有出现的数的绝对值<=10^8。     输入数据不超过5M。

想法

  • 该题的模型就是最远曼哈顿距离
  • 先从k=2的情况分析
  • 观察曼哈顿距离的式子 |x1-x2|+|y1-y2|
  • 将绝对值拆去分类讨论
  • ①x1-x2+y1-y2==>(x1+y1)-(x2+y2)
  • ②x1-x2+y2-y1==>(x1-y1)-(x2-y2)
  • ③x2-x1+y1-y2==>(-x1+y1)-(-x2+y2)
  • ④x2-x1+y2-y1==>(-x1-y1)-(-x2-y2)
  • 发现x1 y1的系数与x2 y2的系数相同 推广到k维

算法

  • 将每一维坐标的系数压成一个二进制位
  • 用Ma[S]表示S状态下的最大值 Mi[S]表示S状态下的最小值
  • ans必然从Ma[S]-Mi[S]中选出

代码

#include <iostream>#include <cstdio>#include <cstdlib>#include <algorithm>#include <cstring>#include <string>#include <cmath>#define MAXN 50005#define INF 1<<30using namespace std;int n,k;typedef long long ll;ll Ma[1<<8],Mi[1<<8],ans;struct Tpoint{    int a[10];}p[MAXN];inline void solve(){    int ind=1<<k;    for (int i=0;i<ind;i++)    {        Ma[i]=-INF;        Mi[i]=INF;    }    for (int i=1;i<=n;i++)    {        for (int j=0;j<ind;j++)        {            ll in=j,s=0;            for (int l=1;l<=k;l++)            {                if(in&1)s+=p[i].a[l];                else s-=p[i].a[l];                in>>=1;            }            if(Ma[j]<s)Ma[j]=s;            if(Mi[j]>s)Mi[j]=s;        }    }    for (int i=0;i<ind;i++)        ans=max(ans,Ma[i]-Mi[i]);    cout<<ans<<endl;}int main(){    //freopen("escape.in","r",stdin);    //freopen("escape.out","w",stdout);    scanf("%d%d",&n,&k);    for (int i=1;i<=n;i++)        for (int j=1;j<=k;j++)            scanf("%d",&p[i].a[j]);    solve();    return 0;}
0 0
原创粉丝点击