判断线段相交 + vector. erase迭代指针 的使用 poj 2653 Pick-up sticks
题目来源:http://poj.org/problem?id=2653
分析:
题意:按顺序给出一些木棍,输出在最上面的木棍标号。
用vector 存储木棍标号, 当前木棍与 vector 中的木棍 相交,则删除该 木棍标号, 注意vector.erase(it) 中 迭代指针的使用。
较简洁的写法:
double add(double a, double b){return (fabs(a + b) < EPS * (fabs(a) + fabs(b))) ? 0 : (a + b) ; } struct Point{double x, y;Point(){}Point(double x, double y):x(x),y(y){}Point operator - (Point a){return Point( add(x , -a.x), add(y , -a.y)) ;}Point operator + (Point a){return Point( add(x , a.x), add(y , a.y)) ;}double operator ^(Point a){return add(x * a.y , -y * a.x) ;}}; bool on_segment(Point p1, Point p2, Point p){return ((p1 - p).x * (p2 - p).x <= 0 )&&((p1 - p).y * (p2 - p).y <= 0) ; } struct Line{Point st , ed ;Line(){}Line(Point s, Point e){st = s ;ed = e ;}bool intersection(Line l){Point p1, p2 ,q1 ,q2 ;p1 = st ;p2 = ed ;q1 = l.st ;q2 = l.ed ;double d1 ,d2 ,d3 ,d4;d1 = (p2 - p1)^(q1 - p1) ;d2 = (p2 - p1)^(q2 - p1) ;d3 = (q2 - q1)^(p1 - q1) ;d4 = (q2 - q1)^(p2 - q1) ;if((d1 == 0 && on_segment(p1, p2 ,q1))||(d2 == 0 && on_segment(p1, p2, q2))|| (d3 == 0 && on_segment(q1 ,q2 ,p1))|| (d4 == 0 && on_segment(q1,q2 ,p2)) )return 1;if(d1 * d2 < 0 && d3 * d4 < 0)return 1;return 0 ;}void read(){scanf("%lf%lf%lf%lf" , &st.x, &st.y ,&ed.x ,&ed.y);}}line[Max_N]; int n; bool ok(int i){for(int j = i+1 ; j < n ; j++){if(line[i].intersection(line[j]))return 0 ;}return 1 ; } vector<int>aa; vector<int>::iterator it; int main() {while(scanf("%d" , &n) && n){aa.clear() ;for(int i= 0 ; i < n ; i++){line[i].read() ;}for(int i = 0 ; i < n ; i++){if(ok(i))aa.push_back(i) ;}printf("Top sticks");int flag = 0 ;for(it = aa.begin() ; it != aa.end() ; it++){if(flag)printf(",") ;else printf(":") ;printf(" %d", (*it + 1)) ;flag = 1;}printf(".\n") ;}return 0 ; }
代码如下:
#include <iostream> #include <algorithm> #include <stdlib.h> #include <stack> #include <iostream> #include <stdio.h> #include <string> #include <string.h> #include <algorithm> #include <stdlib.h> #include <vector> #include <set> #include <math.h> #include <cmath> #include <map> #include <stack> #include <queue>using namespace std ;double EPS=1e-10; // 考虑误差的加法运算 double add(double a,double b) {if(fabs(a+b)<EPS*(fabs(a)+fabs(b))) return 0;return a+b; } struct Point{double x,y;Point(){}Point(double x,double y):x(x),y(y){} // 构造函数,方便代码编写Point operator +(Point p){return Point(add(x,p.x), add(y,p.y));}Point operator-(Point p){return Point(add(x,-p.x),add(y,-p.y));}Point operator*(double d){return Point(x*d,y*d);}double operator*(Point p){ // 内积 点乘return add(x*p.x, y*p.y);}double operator^(Point p){// 外积 叉乘return add(x*p.y,-y*p.x);} }; //判断点p0是否在线段p1p2内 int on_segment(Point p1, Point p2, Point p0) {if (((p1-p0).x * (p2-p0).x <=0 )&& ((p1-p0).y * (p2-p0).y <=0)) // 中间是 &&return 1;return 0; } // 判断线段p1p2与q1是否相交 int intersection(Point p1,Point p2, Point q1,Point q2) {double d1=(p2-p1)^(q1-p1); // 计算p1p2 到q 点的转向 d1>0 左转, d1 <0 右转double d2=(p2-p1)^(q2-p1);double d3=(q2-q1)^(p1-q1);double d4=(q2-q1)^(p2-q1);if((d1==0 && on_segment(p1,p2,q1) )|| (d2==0 && on_segment(p1,p2,q2) )||(d3==0&& on_segment(q1,q2,p1)) || (d4==0 && on_segment(q1,q2,p2)))return 1;else if(d1*d2<0 && d3*d4 <0) // 中间是 &&return 1;return 0; }struct Line{Point st ;Point ed ;Line(){}Line(Point a , Point b){st = a ;ed = b ;}void read(){scanf("%lf%lf%lf%lf" , &st.x , &st.y , &ed.x , &ed.y) ;} }; const int N = 100010; Line line[N]; vector<int>v; vector<int>::iterator it; void solve(int i) {for(it=v.begin(); it!= v.end(); ){if(intersection(line[i].st, line[i].ed,line[*it].st, line[*it].ed ) ){it=v.erase(it); // 删除迭代指针为 it 处的元素, 并返回迭代指针。}else it++;} }int main() {int n;while(cin>>n && n){v.clear();for(int i=1;i<=n;i++){line[i].read();}for(int i=1;i<=n;i++){solve(i);v.push_back(i);}printf("Top sticks");int flag=0;for(it=v.begin() ; it != v.end(); it++){if(flag)printf(", ");else printf(": ");printf("%d",*it);flag=1;}printf(".\n");}return 0; }
转载于:https://www.cnblogs.com/zn505119020/p/3625958.html
判断线段相交 + vector. erase迭代指针 的使用 poj 2653 Pick-up sticks相关推荐
- 判断线段相交(hdu1558 Segment set 线段相交+并查集)
先说一下题目大意:给定一些线段,这些线段顺序编号,这时候如果两条线段相交,则把他们加入到一个集合中,问给定一个线段序号,求在此集合中有多少条线段. 这个题的难度在于怎么判断线段相交,判断玩相交之后就是 ...
- 【计算几何】判断线段相交(跨立实验)
题意:有n条线段(编号为1n),按1n的顺序放在二维坐标系上(就是先放1号,再放2号--),要求输出最上面的那些线段的编号.(就是没有其他线段压在它上面的那些线段) 注意:有交点即为被压. 1.叉积 ...
- 几何基础之判断线段相交问题
1.判断两线段相交 只要判断q1,q2在线段s1s2的两侧和s1,s2在线段q1q2的两侧. q1s1q2s1>0就是在两侧. 2.矩形里有n条直线,一条直线的终点是另一条直线的起点.问矩形被分 ...
- Pipe HDU - 2150(判断线段相交+向量叉乘线代详解)
题目: 经过激烈的争夺,Lele终于把那块地从Yueyue的手里抢了回来.接下来,Lele要开始建造他的灌溉系统. 通过咨询Lele的好友--化学系的TT,Lele决定在田里挖出N条沟渠,每条沟渠输送 ...
- 几何常用算法与判断线段相交【转】
下面这个函数在我写的计算几何库函数里面有,那个库可以在http://algorithm.126.com/的资源中心 - 代码角 找到. 算法简单说明: 首先判断以两条线段为对角线的矩形是否 ...
- HDU1086You can Solve a Geometry Problem too(判断线段相交)
You can Solve a Geometry Problem too Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/3 ...
- 德莱联盟[判断线段相交]
德莱联盟 时间限制:1000 ms | 内存限制:65535 KB 难度:1 描述 欢迎来到德莱联盟.... 德莱文... 德莱文在逃跑,卡兹克在追.... 我们知道德莱文的起点和终点坐标,我们也 ...
- NYOJ1016(德莱联盟)(判断线段相交)
德莱联盟 时间限制:1000 ms | 内存限制:65535 KB 难度:1 描述 欢迎来到德莱联盟.... 德莱文... 德莱文在逃跑,卡兹克在追.... 我们知道德莱文的起点和终点坐标,我们也 ...
- POJ 2653 Pick-up sticks 判断线段相交
枚举每条线段 这条线段上面没有与它相交的线段 #include <iostream> #include <cstdio> #include <cstring> #i ...
最新文章
- GitHub-jekyll静态博客快速构建与优化--jekyll serve --incremental --profile
- 图解TCP、IP笔记
- PINVOKE.NET: Do interop the wiki way!
- inner join 和 exists 效率_19条效率至少提高3倍的MySQL技巧
- json文件转为excel_2分钟上手、3小时学会无代码软件开发---XML、Json处理
- 适用于Mac OS X的官方Java 7 –状态
- linux网站465端口是什么端口,发送端口25,465,587端口疑问解答
- [原创]Scala学习:编写Scala脚本
- android上传图片失败问题
- 计算机关闭的时候自动更新,win7自动更新关闭有什么影响_win7系统关闭自动更新的步骤-win7之家...
- 关于文件服务器共享文件的备份与恢复
- 微信小程序:未找到 app.json 中的定义的 pages “pages/index/index“ 对应的 WXML 文件
- CentOS6.5下搭建LAMP+FreeRadius+Daloradius Web管理和TP-LINK路由器、H3C交换机连接,实现,上网认证和记账功能
- linux分区方案为user,Ubuntu 为用户分配磁盘空间Linux 硬盘分区方案
- 05 - Protege OWL API 的使用 - 本科毕设整理
- iOS开发之Objective-C(基础篇)-李飞-专题视频课程
- symbian字体使用方法汇总
- 《三体》中超级悲壮的话有哪些?
- 生成微信公众号二维码(用户扫码关注公众号)
- 1. 我的自学编程之路