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;
}


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