poj - 2926 - Requirements(多维曼哈顿距离)

题目链接:https://ac.nowcoder.com/acm/contest/16/B

思路:二维空间上两个坐标之间的曼哈顿距离(x1, y1)(x2, y2)|x1-x2| +|y1-y2|去掉绝对值符号后共有下列四种情况:

\left \{ (x1-x2) + (y1-y2) \right \}

\left \{ (x1-x2) + (y2-y1)\right \}

\left \{ (x2-x1)+ (y1-y2) \right \}

\left \{ (x2-x1) + (y2-y1) \right \}

转化一下:

\left \{ (x1+y1) - (x2+y2) \right \}

\left \{ (x1-y1) - (x2-y2) \right \}

\left \{ (-x1+y1)- (-x2+y2)\right \}

\left \{ (-x1-y1)- (-x2-y2)\right \}

显然,任意给两个点,我们分别计算上述四种情况,那么最大值就是曼哈顿距离。如果我们用1表示+号,用0表示-号那么对应为:

\left \{ (x1+y1) - (x2+y2) \right \}\leftrightarrow(1,1,1,1)

\left \{ (x1-y1) - (x2-y2) \right \}\leftrightarrow (1,0,1,0)

\left \{ (-x1+y1)- (-x2+y2)\right \}\leftrightarrow (0,1,0,1)

\left \{ (-x1-y1)- (-x2-y2)\right \}\leftrightarrow (0,0,0,0)

所以我们可以二进制枚举即可,也就是枚举2^{2}种情况,扩展到n维也是一个道理,无非是枚举2^{n}种情况。

#include 
#include 
#include 
using namespace std;
typedef long long ll;
typedef unsigned long long ul;
const int inf = 0x3f3f3f3f;
const ll INF = 0x3f3f3f3f3f3f3f3fLL;
const int mod = 998244353;
const double eps = 1e-8;

const int N = 1e5 + 7;
int n;
double x, a[N][10];
double get_Manhattan(int d) //d维曼哈顿,两点之间最大值
{
    double ans = 0;
    for(int i = 0; i < (1 << d); i++)
    {
        double mi = inf, mx = -inf;
        for(int k = 0; k < n; k++)
        {
            double t = 0;
            for(int j = 0; j < d; j++)
            {
                if(i & (1 << j)) t += a[k][j];
                else t -= a[k][j];
            }
            mi = min(mi, t);
            mx = max(mx, t);
        }
        ans = max(mx - mi, ans);
    }
    return ans;
}
int main()
{
    while(~scanf("%d",&n))
    {
        for(int i = 0; i < n; i++)
            for(int j = 0; j < 5; j++)
                scanf("%lf", &a[i][j]);
        double ans = get_Manhattan(5);
        printf("%.2f\n", ans);
    }
}

 

 

你可能感兴趣的:(【欧拉回路/路径/曼哈顿距离】)