UVA 10902 POJ 2653 Pick-up sticks【线段规范相交】【图】

来源:互联网 发布:山西农大软件学院 编辑:程序博客网 时间:2024/06/05 14:35

题目大意:给出火柴(线段)的起点终点,有童鞋无聊按输入顺序扔火柴,求最后所有没有被其他火柴压住的火柴序号。

解题策略:第一反应想到的算法很简单:

                    1,火柴只能被后来的火柴可能压住 <=> 火柴只能和后来的火柴“相交” ,之前的火柴不考虑;

                    2,“相交”  <=> "规范相交",这里是关键;(详见下图)

                    3,查找的时候可以优化,提升效率,第一时间想的算法过掉了;


附:

非规范相交:


规范相交:




/*   UVA 10902 POJ 2653 Pick-up sticks   AC by J_Dark   ON 2013/5/3 0:00   Time 0.0.345s*/#include <iostream>#include <cstdio>#include <cstring>#include <cmath>#include <climits>#include <vector>#include <algorithm>using namespace std;///////////////////////////////////////////struct point{double x, y;point(double p=0, double q=0){x = p;y = q;}};struct line{point a, b;line(point x, point y){a = x;b = y;}};int segNum;vector<line> Seg;vector<int> topSeg;///////////////////////////////////////////void Input(){Seg.clear();topSeg.clear();double ax, ay, bx, by;for(int i=0; i<segNum; i++){cin >> ax >> ay >> bx >> by;point start(ax, ay), end(bx, by);Seg.push_back(line(start, end));}}double Direction(point Pi, point Pj, point Pk){return (Pj.x-Pi.x)*(Pk.y-Pi.y)-(Pk.x-Pi.x)*(Pj.y-Pi.y);}bool isIntersect(line p, line q){  double d1, d2, d3, d4;  d1 = Direction(p.a, p.b, q.a);  d2 = Direction(p.a, p.b, q.b);  d3 = Direction(q.a, q.b, p.a);  d4 = Direction(q.a, q.b, p.b);  if(d1*d2<0 && d3*d4<0)  { return true;}  //规范相交  //非规范相交  else return false;}void Compute(){bool ff;//这里可以优化,大大提高效率for(int i=0; i<segNum; i++){ff = false;for(int k=i+1; k<segNum; k++){if( isIntersect(Seg[i], Seg[k]) ){ff = true;break;}}if(!ff)  topSeg.push_back(i+1);}}void Output(){cout << "Top sticks: ";for(int i=0; i<topSeg.size(); i++){if(i>0)  cout << ", " << topSeg[i];else cout << topSeg[i];}cout << "." << endl;}///////////////////////////////////////////////////////int main(){while(cin >> segNum && segNum){Input();Compute();Output();}return 0;}


原创粉丝点击