题意: 有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; }