您的位置:首页 > 其它

UVa 1511 - Soju

2015-08-03 17:29 260 查看
网上有其他的贪心做法 , 我介绍另外一个思路(如yifan 和 purefrog)

抓住题目一个条件 , p1的所有点的x坐标都比p2的小

对于p1的点来说 , 如果有i , j , 且xi>xj , abs(yi-yj)<= xi-xj 那么点j 将是没有意义的 , 想想为什么 ,p2点集的同理可见

[以下是对p1的操作的证明 , p2的同理啦

提示:
s1 s2 为p1点集中的两个点,且满足s1.x>s2.x ;
s3为p2点集中的**任意**一个点

d1 = s3.x-s1.x+abs(s3.y-s1.y);
d2 = s3.x-s2.x+abs(s3.y-s2.y);
d1-d2 = s2.x-s1.x+abs(s3.y-s1.y)-abs(s3.y-s1.y+(s1.y-s2.y))
如果d1-d2恒小于等于0 , 那么s2就是没有意义的
d1-d2<=0
-> s1.x-s2.x>=abs(s3.y-s1.y)-abs(s3.y-s1.y+(s1.y-s2.y))
>=abs(s3.y-s1.y)-(abs(s3.y-s1.y)+abs(s1.y-s2.y))
= abs(s1.y-s2.y)




以上是很严格的推倒 , 但是其实想象一下也就可以了,对于p1的两个点 , 到p2任何一个点的曼哈顿距离取决于x和y , 而无论p2中取哪个点x的差别是一定的 , 如果x坐标相对离得较远的点想在总距离上追赶上x坐标离得近的那个点 , 肯定y要更靠近 , 并且比另一个要靠近的距离要大于两个x坐标的绝对值 , 但是如果两个y的差的绝对值都不及x的差的绝对值的话肯定是不行的;

//
//  main.cpp
//  UVa1511
//
//  Created by Fuxey on 15/8/3.
//  Copyright (c) 2015年 corn.crimsonresearch. All rights reserved.
//

#include <iostream>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <cmath>
#include <algorithm>

using namespace std;
typedef pair<int, int> pii;
pii a[110000] , b[110000] , aa[110000] , bb[110000];

int main(int argc, const char * argv[]) {

int t;
scanf("%d",&t);
while(t--)
{
int n , m;
scanf("%d",&n);
for(int i=1;i<=n;i++) scanf("%d%d",&a[i].first,&a[i].second);
scanf("%d",&m);
for(int i=1;i<=m;i++) scanf("%d%d",&b[i].first,&b[i].second);
sort(a+1, a+1+n);
sort(b+1, b+1+m);

int ca=0 , cb=0;
for(int i=n;i>=1;i--)
{
bool ok=1;
for(int j=1;j<=ca;j++)
if(aa[j].first-a[i].first>= abs(aa[j].second-a[i].second)) { ok=0; break; }
if(ok) aa[++ca] = a[i];
}

for(int i=1;i<=m;i++)
{
bool ok=1;
for(int j=1;j<=cb;j++) if(b[i].first-bb[j].first>= abs(bb[j].second-b[i].second)) { ok=0; break; }
if(ok) bb[++cb] = b[i];
}
int ans = (1<<30);
for(int i=1;i<=ca;i++) for(int j=1;j<=cb;j++) ans = min(ans , abs(aa[i].first-bb[j].first)+abs(aa[i].second-bb[j].second));
printf("%d\n",ans);
}

return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  uva