1. 程式人生 > >hdu-4666-Hyperspace-最長曼哈頓距離

hdu-4666-Hyperspace-最長曼哈頓距離

題意:

給定一些操作(0代表新增一個點,1代表刪除一個點),求這些點的最遠曼哈頓距離。

做法:

只考慮二維空間上兩個座標之間的曼哈頓距離(x1, y1) 和 (x2, y2),|x1-x2| +|y1-y2|去掉絕對值符號後共有下列四種情況

(x1-x2) + (y1-y2), (x1-x2) + (y2-y1), (x2-x1) + (y1-y2), (x2-x1) + (y2-y1)

轉化一下:

(x1+y1) - (x2+y2), (x1-y1) - (x2-y2), (-x1+y1) - (-x2+y2), (-x1-y1) - (-x2-y2)

顯然,任意給兩個點,我們分別計算上述四種情況,那麼最大值就是曼哈頓距離。

轉化後,“-”號兩側的座標形式是一樣的。維數為5,因此我們可以用二進位制列舉。

最大曼哈頓距離 = max{每種情況下的最大值-最小值};

用multiset儲存每種情況的值。

#include<stdio.h>
#include<iostream>
#include<algorithm>
#include<set>
using namespace std;
#define maxn 60002
int maps[maxn][6];
multiset<int>se[1<<5];
multiset<int>::iterator i1,i2;
int main()
{
    int i,j,leap,x,n,m,a;
    while(~scanf("%d%d",&n,&m))
    {
        for(i=0;i<(1<<5);i++)
            se[i].clear();
        for(i=1;i<=n;i++)
        {
            scanf("%d",&leap);
            if(leap==0)
            {
                for(j=0;j<m;j++)
                {
                    scanf("%d",&maps[i][j]);
                }
                for(a=0;a<(1<<m);a++)
                {
                    int as;
                    as=0;
                    for(j=0;j<m;j++)
                    {
                        if(a&(1<<j))as+=maps[i][j];
                        else as-=maps[i][j];
                    }
                    se[a].insert(as);
                }
            }
            else
            {
                scanf("%d",&x);
                for(a=0;a<(1<<m);a++)
                {
                    int as;
                    as=0;
                    for(j=0;j<m;j++)
                    {
                        if(a&(1<<j))as+=maps[x][j];
                        else as-=maps[x][j];
                    }
                    i1=se[a].find(as);
                    se[a].erase(i1);
                }
            }
            int ans=0;
            for(a=0;a<(1<<m);a++)
            {
                i1=se[a].begin();
                i2=se[a].end();
                i2--;
                ans=max(ans,(*i2)-(*i1));
            }
            cout<<ans<<endl;
        }
    }
    return 0;
}