UVALive - 5848 Soju
2015-08-15 14:18
344 查看
传送门 https://icpcarchive.ecs.baylor.edu/index.php?option=com_onlinejudge&Itemid=8&page=show_problem&problem=3859
让人印象深刻的一道题
思路 :
分治去求会TLE , but 暴力就好。。。。。。。ORZ
Dis(P1,P2)=|x1−x2|+|y1−y2|
因为题目保证第一部分的点的横坐标一定小于第二部分。
=x2−x1+|y1−y2|
然后分类讨论。当y1>=y2时,原式=(x2−y2)+(y1−x1)
我们可以想到,如果我们把全部的点混合起来,按照y从小到大排序。
如果当前的点是part1,那么y1−x1可以立刻算出来,而x2−y2可以通过维护前面的part2点的最小值的得来。
所以,我们一边维护x2−y2的最小值,一边维护ans。
所以当我们过一遍数组之后,就有了一个暂时的答案ans。
为什么是暂时的?
因为还要考虑y2>y1的情况。
同理,当y2>y1 时, 原式=(x2+y2)−(x1+y1).
可以维护x1+y1的最大值来得到ans。
重新扫描一遍数组。
TLE 的分治贴出来,
让人印象深刻的一道题
思路 :
分治去求会TLE , but 暴力就好。。。。。。。ORZ
Dis(P1,P2)=|x1−x2|+|y1−y2|
因为题目保证第一部分的点的横坐标一定小于第二部分。
=x2−x1+|y1−y2|
然后分类讨论。当y1>=y2时,原式=(x2−y2)+(y1−x1)
我们可以想到,如果我们把全部的点混合起来,按照y从小到大排序。
如果当前的点是part1,那么y1−x1可以立刻算出来,而x2−y2可以通过维护前面的part2点的最小值的得来。
所以,我们一边维护x2−y2的最小值,一边维护ans。
所以当我们过一遍数组之后,就有了一个暂时的答案ans。
为什么是暂时的?
因为还要考虑y2>y1的情况。
同理,当y2>y1 时, 原式=(x2+y2)−(x1+y1).
可以维护x1+y1的最大值来得到ans。
重新扫描一遍数组。
#include <iostream> #include <cstdio> #include <cstring> #include <cmath> #include <algorithm> using namespace std; struct point { int x,y; int ty; }; point a[200010]; int cmpy(point a, point b) //对点的y坐标排序; { return a.y<b.y; } int dis(point a,point b) { return abs(a.x - b.x) + abs(a.y - b.y); } int main() { int t; scanf("%d",&t); while(t--) { int n, m; scanf("%d",&n); for(int i = 0; i < n; i++) scanf("%d %d",&a[i].x , &a[i].y), a[i].ty = 0; scanf("%d",&m); for( int j = 0; j < m; j++) scanf("%d %d",&a[n + j].x , &a[n + j].y), a[n + j].ty = 1; sort(a, a + n + m, cmpy); int i = 0, j = 0; int ans = 0x3f3f3f3f, tmp = 0x3f3f3f3f; for (int i = 0; i < n + m; i++) { if (a[i].ty) tmp = min(tmp, a[i].x - a[i].y); else ans = min(ans, a[i].y - a[i].x + tmp); } tmp = -0x3f3f3f3f; for (int i = 0; i < n + m; i++) { if (a[i].ty) ans = min(ans, a[i].x + a[i].y - tmp); else tmp = max(tmp, a[i].x + a[i].y ); } printf("%d\n",ans); } return 0; }
TLE 的分治贴出来,
#include <iostream> #include <algorithm> #include <cstdio> #include <cmath> #include <cstdlib> using namespace std; struct POINT { int x,y; int flag; }point[200010],temp1[100010],temp2[100010]; int dis(POINT p1, POINT p2) { if(p1.flag != p2.flag) return fabs(p1.x - p2.x)+ fabs(p1.y - p2.y); else return 100000000; } bool cmp(POINT a, POINT b) { return a.x < b.x; } int findMin(int l, int r) { if (l == r) { return 100000000; } if (l == r - 1) { return dis(point[l], point[r]); } int mid =(l + r) >> 1; int tmp1 = findMin(l,mid); int tmp2 = findMin(mid + 1, r); int Mindis,tmp; int i,j; Mindis = tmp1 < tmp2 ? tmp1 : tmp2; int cnt1 = 0; int cnt2 = 0; for (i = mid; i >= l; -- i) { if ((point[mid].x - point[i].x) < Mindis) { temp1[cnt1 ++] = point[i]; } } for (i = mid + 1; i <= r; ++ i) { if ((point[i].x - point[mid].x) < Mindis) { temp2[cnt2 ++] = point[i]; } } for (i = 0; i < cnt1; ++ i) { for (j = 0; j < cnt2; ++ j) { tmp = dis(temp1[i], temp2[j]); if (tmp < Mindis) { Mindis = tmp; } } } return Mindis; } int main() { int n,i,t; int minDis ; scanf("%d", &t); while (t -- ) { scanf("%d", &n); minDis = 100000000; for (i = 0; i < n; ++ i) { scanf("%d%d", &point[i].x, &point[i].y); point[i].flag = 1; } int m; scanf("%d",&m); for (int j = 1; j <= m; ++ j) { scanf("%d%d", &point[i].x, &point[i].y); point[i].flag = 2; i++; } n = n + m; sort(point, point + n, cmp); minDis = findMin(0, n-1); printf("%d\n", minDis); } return 0; }
相关文章推荐
- 整除的尾数
- hdu 2853 — Assignment
- 移动app接口编程技术-学习实现之PHP 字符串
- 2015第33周六
- POJ 3436 ACM Computer Factory
- spring mvc poi excel
- 【免费讲座IX算法第一阶段】转专业找CS工作“打狗棒法”
- 线上测试高可用集群部署文档【我的技术我做主】
- Android 之数值单位转换
- 树莓派用python写几个简单程序2_GPIO控制
- Matlab:RandStream函数
- 邮件系统的分布式系统架构
- MyEclipse eclipse 修改注释的作者名字
- struts2集成spring3的原理分析
- Cocos2d-js 使用cc.Animation实现跑酷
- Could not find action or result: /SendMail/servlet/UploadServlet
- 生活日记2015-8-15
- 不使用split和replace情况下分割复杂字符串
- 移动前端开发之viewport的深入理解
- 梦想与皇后