Requirements POJ - 2926

http://poj.org/problem?id=2926

一道裸题 计算k维空间两点最远曼哈顿距离 复杂度n*k*(2^k)

考虑二维平面两点(xi,yi) (xj,yj) 两者曼哈顿距离为|xi-xj|+|yi-yj| 去掉绝对值后可能有以下四种形式

(xi-xj)+(yi-yj) (xj-xi)+(yi-yj) (xi-xj)+(yj-yi) (xj-xi)+(yj-yi)

同一点的坐标放在一起后

(xi+yi)-(xj+yj) (-xi+yi)-(-xj+yj) (xi-yi)-(xj-yj) (-xi-yi)-(-xj-yj)

发现两点对应维度坐标的符号相同 而曼哈顿距离最远的两个点之间同样如此 所以2^k枚举所有符号取向 再对n个点求出当前情况下的k个坐标相加之和 取最大最小值即可

#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std;

double per[100010][10];
double maxx[50],minn[50];
int pre[50];
int n;

double getmax(double a,double b)
{
    if(a>b) return a;
    else return b;
}

double getmin(double a,double b)
{
    if(a<b) return a;
    else return b;
}

double solve()
{
    double sum;
    int i,j,k;
    for(i=0;i<32;i++)
    {
        maxx[i]=-1000000000000000000.0;
        minn[i]=1000000000000000000.0;
    }
    for(i=1;i<=n;i++)
    {
        for(j=0;j<32;j++)
        {
            sum=0.0;
            for(k=0;k<5;k++)
            {
                if(j&pre[k]) sum+=per[i][k];
                else sum-=per[i][k];
            }
            maxx[j]=getmax(maxx[j],sum);
            minn[j]=getmin(minn[j],sum);
        }
    }
    sum=0.0;
    for(j=0;j<32;j++) sum=getmax(sum,maxx[j]-minn[j]);
    return sum;
}

void init()
{
    int i;
    pre[0]=1;
    for(i=1;i<=30;i++) pre[i]=2*pre[i-1];
}

int main()
{
    int i,j;
    init();
    scanf("%d",&n);
    for(i=1;i<=n;i++)
    {
        for(j=0;j<5;j++) scanf("%lf",&per[i][j]);
    }
    printf("%.2f\n",solve());
    return 0;
}

猜你喜欢

转载自blog.csdn.net/sunyutian1998/article/details/82178108