[Swust OJ 567]--老虎在不在笼子里(凸包问题)
2015-06-13 00:14
525 查看
题目链接:http://acm.swust.edu.cn/problem/567/
Time limit(ms): 1000 Memory limit(kb): 65535
一只老虎自从看了<越狱>以来,脾气就比较暴躁,而且变得神神秘密的.一天管理员发现老虎不见了,这下他可急坏了,赶紧通知了110.幸好这只老虎身上装了GPS,所以还有希望找到他.
你的任务就是通过GPS给出的老虎的坐标和笼子的坐标来让电脑计算出老虎的位置,是躲在洞里了,还是跑到外面去了.
Description
输入数据有N+2行:
第一行是一个数据N(0<=N<=12),代表了笼子的坐标X,Y的个数(X,Y都在INT范围内);
第二到N+1行是N个坐标X,Y,依次按从下逆时针的顺序来给出的.
最后一行是老虎的坐标X,Y;
注:只有一组测试数据,输入的都是整数,笼子一定是凸多边形,而且老虎也不会出现在笼子边界上
三角形的面积可以用向量的外积来计算,那么多边形是N个三角形,那么就可以。。。。。
Input
如果老虎还在笼子里,输入"YES",否则是"NO";
Output
Sample Input
Sample Output
解题思路:这道题看上去可能会以为是一个很坑的数学问题,但是仔细读题就会发现
这道题其实就是比较笼子构成的凸包面积,和加入老虎坐标新的点集构成的新凸包的面积
是否相等的题,相等即老虎在笼子内,反之亦然~~
关于凸包的问题,可以戳戳这里:http://www.cnblogs.com/zyxStar/p/4540984.html
代码如下:
View Code
Time limit(ms): 1000 Memory limit(kb): 65535
一只老虎自从看了<越狱>以来,脾气就比较暴躁,而且变得神神秘密的.一天管理员发现老虎不见了,这下他可急坏了,赶紧通知了110.幸好这只老虎身上装了GPS,所以还有希望找到他.
你的任务就是通过GPS给出的老虎的坐标和笼子的坐标来让电脑计算出老虎的位置,是躲在洞里了,还是跑到外面去了.
Description
输入数据有N+2行:
第一行是一个数据N(0<=N<=12),代表了笼子的坐标X,Y的个数(X,Y都在INT范围内);
第二到N+1行是N个坐标X,Y,依次按从下逆时针的顺序来给出的.
最后一行是老虎的坐标X,Y;
注:只有一组测试数据,输入的都是整数,笼子一定是凸多边形,而且老虎也不会出现在笼子边界上
三角形的面积可以用向量的外积来计算,那么多边形是N个三角形,那么就可以。。。。。
Input
如果老虎还在笼子里,输入"YES",否则是"NO";
Output
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 | 4 0 0 1 0 1 1 0 1 0.5 0.5 6 1 -1 2 0 1 1 -1 1 -2 0 -1 -1 3 3 |
1 2 | YES NO |
解题思路:这道题看上去可能会以为是一个很坑的数学问题,但是仔细读题就会发现
这道题其实就是比较笼子构成的凸包面积,和加入老虎坐标新的点集构成的新凸包的面积
是否相等的题,相等即老虎在笼子内,反之亦然~~
关于凸包的问题,可以戳戳这里:http://www.cnblogs.com/zyxStar/p/4540984.html
代码如下:
//只需要判断加入该点凸包面积,和笼子构成凸包面积是否相等即可 #include<iostream> #include<cstdio> #include<algorithm> #include<stack> #include<cmath> using namespace std; struct node{ double x, y; }point[110], tiger[101], posA, posB, tmp;//posB老虎基准量 double dis(node a, node b){ return pow((a.x - b.y), 2) + pow((a.y - b.y), 2); } //按点集分布排序,利用向量平行关系判断 bool cmp(node a, node b){ double povit = (a.x - posA.x)*(b.y - posA.y) - (b.x - posA.x)*(a.y - posA.y); if (povit > 0 || !povit && (dis(a, posA) < dis(b, posA))) return true; return false; } //当前点是否在点集左侧,利用叉乘比较3个点两条线的斜率关系 bool turn_left(node p1, node p2, node p3){ return (p2.x*p1.y + p3.x*p2.y + p1.x*p3.y - p3.x*p1.y - p1.x*p2.y - p2.x*p3.y) > 0 ? true : false; } int main(){ int i, sign1, sign2, n; double area1, area2; cin >> n; for (i = 0; i < n; i++){ cin >> point[i].x >> point[i].y; tiger[i].x = point[i].x; tiger[i].y = point[i].y; } cin >> tiger[i].x >> tiger[i].y;//老虎坐标 stack<node> Q; sign1 = 0; posA = posB = point[0]; //分别找到笼子,加入老虎坐标 的点集的最左下的点 for (i = 1; i < n + 1; i++){ if (i<n){ if (posA.y == point[i].y&&posA.x>point[i].x || point[i].y < posA.y){ posA = point[i]; sign1 = i; } } else{ posB = posA; sign2 = sign1; if (posB.y == tiger[i].y&&posB.x>tiger[i].x || tiger[i].y < posB.y){ posB = tiger[i]; sign2 = i; } } } swap(point[0], point[sign1]); swap(tiger[0], tiger[sign2]); sort(point + 1, point + n, cmp);//利用叉乘按点集离散化,方便筛选构成图凸包有效的点 sort(tiger + 1, tiger + n + 1, cmp); Q.push(tiger[0]), Q.push(tiger[1]), Q.push(tiger[2]); for (i = 3; i < n + 1; i++){ while (!Q.empty()){ tmp = Q.top(); Q.pop(); if (turn_left(tmp, Q.top(), tiger[i])){ Q.push(tmp); break; } } Q.push(tiger[i]); } //由于给出笼子必为凸包,直接计算面积 area1 = area2 = 0; tmp = point[n - 1]; area1 += (posA.x*tmp.y - posA.y*tmp.x) / 2.0; for (i = n - 2; i >= 0; i--){ area1 += (tmp.x*point[i].y - tmp.y*point[i].x) / 2.0; tmp = point[i]; } tmp = Q.top(), Q.pop(); area2 += (posA.x*tmp.y - posA.y*tmp.x) / 2.0; while (!Q.empty()){ area2 += (tmp.x*Q.top().y - tmp.y*Q.top().x) / 2.0; tmp = Q.top(); Q.pop(); } printf("%s\n", area1 == area2 ? "YES" : "NO"); return 0; }
View Code
相关文章推荐
- 使用Java完成《算法导论》习题2.1-4
- 二叉树前序、中序、后序遍历非递归写法的透彻解析
- 面试题目随记
- WIN7下安装SVN服务器端及客户端搭建协作环境
- Redis学习笔记-Jedis操作Redis
- 网页基本知识
- String数据类型详解
- 数据类型
- TFS大文件分析
- 字符串
- 远程计算_使用Matlab计算引擎
- scanf sscanf fscanf fgets printf sprintf snprintf 等函数
- OpenGL 键盘控制和灯光
- Light OJ 1025 The Specials Menu(区间DP)
- 0. 序列
- FIQ和IRQ的区别及CPU实现
- 马云——2015纽约经济俱乐部演讲全文
- ELF Format 笔记(二)—— ELF Header
- CString时间字符串,COleDateTime,CTime类之间的转换
- ASP.NET中母版页和shtml实例入门