hdu 4666 Hyperspace

可以添加和删除点,问这些点中两点间的最大曼哈顿距离

曼哈顿距离:(x0,y0,z0)  (x1,y1,z1)   d=|x0-x1|+|y0-y1|+|z0-z1|

去掉绝对值符号,整理后发现 d=(+-x0+-y0+-z0)-(+-x1+-y1+-z1)     ***前后括号中对应的符号相同***

因此只需记录相应符号下的最大,最小值即可

应用set  ,set中的元素默认是按从小到大的顺序的,因此感觉可以取代优先队列

multiset中的元素可重复,set中不可以

.find() 返回迭代器  .erase()是删除,参数也为迭代器

#include<iostream>
#include<set>
using namespace std;
multiset<int> mset[1<<5];
int num[60010][6];
int main()
{
    std::ios::sync_with_stdio(false);
    int q,k;
    while(cin>>q>>k)
    {
        for(int i=0;i<(1<<5);i++)
        {
            mset[i].clear();
        }
        int a;
        for(int i=1;i<=q;i++)
        {
            cin>>a;
            if(!a)
            {
                for(int x=0;x<k;x++) cin>>num[i][x];
                for(int x=0;x<(1<<k);x++)
                {
                    int sum=0;
                    for(int j=0;j<k;j++)
                    {
                        if(x&(1<<j)) sum+=num[i][j];
                        else sum-=num[i][j];
                    }
                    mset[x].insert(sum);
                    //cout<<sum;
                }
            }
            else
            {
                int b;
                cin>>b;
                for(int j=0;j<(1<<k);j++)
                {
                    int sum=0;
                    for(int x=0;x<k;x++)
                    {
                        if(j&(1<<x)) sum+=num[b][x];
                        else sum-=num[b][x];
                    }
                    multiset<int>::iterator it0;
                    it0=mset[j].find(sum);
                    mset[j].erase(it0);
                }
            }
            int maxx=0;
            for(int j=0;j<(1<<k);j++)
            {
                multiset<int>::iterator it1,it2;
                it1=mset[j].begin();
                it2=mset[j].end();
                it2--;
                //cout<<*it1<<" "<<*it2<<endl;
                //cout<<*it1-*it2<<" ";
                //for(it1;it1!=it2;it1++) cout<<*it1<<" ";
                //cout<<endl;
                maxx=max(maxx,(*it2)-(*it1));
            }
            cout<<maxx<<endl;

        }
    }
}


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值