HDU-4666 最远曼哈顿距离

45 篇文章 0 订阅

题目连接

此题值得分析:

曼哈顿距离:两个点所对应的坐标差的绝对值之和。比如在一维空间:x1,x2.   d=|x1-x2|,二维空间:(x1,y1),(x2,y2)    d=|x1-x2|+|y1-y2|     三维空间(x1,y1,z1),(x2,y2,z2)

d=|x1-x2|+|y1-y2|+|z1-z2|,以此类推。。。

看到绝对值,我们就想到去绝对值。如果在二维空间:d=|x1-x2|+|y1-y2|

拆开:x1-x2+y1-y2,       x1-x2+y2-y1,           x2-x1+y1-y2,           x2-x1+y2-y1     每个绝对值的里面去了有2种,有n维空间,就有2*2*2.......2=>2^n

在把上面的整理一下有:(x1+y1)+(-x2-y2) , (-x1+y1)+(x2-y1),(x1-y1)+(-x2+y2),(-x1-y1)+(x2+y2);

再看对应每个点:(x1+y1),(-x1+y1),(x1-y1),(-x1-y1)和      (x2+y2),(-x2+y2),(x2-y2),(x2+y2)  

这样就可以把每个点的2^n种情况计算出来了这样就可以其他点做差,取出最大的就行了

代码:

#include<cstdio>
#include<cstring>
#include<set>
using namespace std;

multiset<int>mt[32];
multiset<int>::iterator it1,it2;
int a[60005][6];

int main()
{
	int n,m,i,j,k;
	int od,x,tmp,ret;
	while(scanf("%d %d",&n,&m)!=EOF){
		for(i=0;i<32;i++) mt[i].clear();				
		for(i=1;i<=n;i++){
			scanf("%d",&od);
			if(od==0){
				for(j=0;j<m;j++)
					scanf("%d",&a[i][j]);
					for(j=0;j<(1<<m);j++){
						tmp=0;
						for( k=0;k<m;k++)
							if(j&(1<<k)) tmp+=a[i][k];
							else tmp-=a[i][k];
						mt[j].insert(tmp);
					}
			}
			else{
				scanf("%d",&x);
				for(j=0;j<(1<<m);j++){
					tmp=0;
					for(k=0;k<m;k++)
						if(j&(1<<k)) tmp+=a[x][k];
						else tmp-=a[x][k];
					it1=mt[j].find(tmp);
					mt[j].erase(it1);
				}
			}
		   ret=0;
		   for(j=0;j<(1<<m);j++){
			it1=mt[j].end();
			it1--;
			it2=mt[j].begin();
			ret=max(ret,(*it1)-(*it2));
		    }
		    printf("%d\n",ret);
	    }
	}
	return 0;
}



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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值