题意: 有Q个操作。 没次操作会增加一个点, 或者删除一个点。 每次输出点集的最大曼哈顿距离。
思路: STL应用
一维就是 Max (x) - Min(x)
就是对于 二维的 x - y 和 x + y 做两个集合。 答案肯定会在 Max( x - y) - Min( x - y) 或者 是 Max(x + y) - Min(x + y)
而三维就是 Max(x + y + z) - Min(x + y + z) 或者是 Max(x + y - z) - Min(x + y - z) 略。
就是 +-a +- b +- c +- d +- e
把每种情况用二进制表示成一个状态枚举一下就可以了。
#include <iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<map>
#include<set>
using namespace std;
map<int,int>h[35];
map<int,int>::iterator it;
multiset<int>myset[35];
multiset<int>::iterator it2,i1,i2;
const int oo=-1e9;
int ab(int a)
{
return a<0?-a:a;
}
int main()
{
int n,k,s,co[8],num,xu;
while(~scanf("%d%d",&n,&k))
{
int od=1<<k;
for(int i=0; i<od; i++)
h[i].clear(),myset[i].clear();
num=1;
for(int num=1; num<=n; num++)
{
scanf("%d",&s);
if(!s)
{
for(int i=0; i<k; i++)scanf("%d",&co[i]);
for(int i=0; i<od; i++)
{
int ans=0,sym=i;
for(int j=0; j<k; j++)
{
if(sym&1) ans+=co[j];
else ans-=co[j];
sym>>=1;
}
h[i][num]=ans;
myset[i].insert(ans);
}
}
else
{
scanf("%d",&xu);
for(int i=0; i<od; i++)
{
it=h[i].find(xu);
it2=myset[i].find(it->second);
myset[i].erase(it2);
h[i].erase(it);
}
}
if(h[0].size()==0)
{
puts("0");
continue;
}
int ret=oo;
for(int i=0; i<od; i++)
{
i1=myset[i].begin(),i2=myset[i].end();
i2--;
ret=max(ret,ab(*i1-*i2));
}
printf("%d\n",ret);
}
}
return 0;
}