UVA 866 Intersecting Line Segments【线段规范相交简单变形】

题目大意:给出一组线段,若每组线段有相交,则线段有交点处断开,生成新的线段,求出最后所有线段数目
解题策略:经过验证,该题相交情况为“规范相交”,难度大大降低。

                    我的核心算法是:对一个线段来说,记录它与其他所有线段规范相交点的数目,断开生成新线段数目 = 相交点数目+1。


/*
   UVA 866 Intersecting Line Segments
   AC by J_Dark
   ON 2013/5/3
   Time 0.009s
*/
#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;
		nn = 0;
	}
	int nn;
};
int segNum;
vector <line> Seg;
///////////////////////////////////////////
void Input(){
	Seg.clear();
	double ax, ay, bx, by;
	cin >> segNum;
	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(){
	int newSegNum = 0;
	for(int i=0; i<segNum; i++){
		for(int k=0; k<segNum; k++){
			if(i != k){
			   if(isIntersect(Seg[i], Seg[k]))
				  Seg[i].nn++;
			}
		}
		newSegNum += (Seg[i].nn + 1);
	}
	/*for(int i=0; i<segNum; i++){
	   cout << Seg[i].nn << endl;}*/
	cout << newSegNum << endl;
}
///////////////////////////////////////////////////////
int main(){
    int testCase;
	while(cin >> testCase)
	{
		getchar();
		getchar();
		for(int i=0; i<testCase; i++){
			if(i>0) cout << endl;
			Input();
		    Compute();
		}
	}
	return 0;
}


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章