UVA 11343 Isolated Segments【判断线段相交】

题目大意:求出孤立线段数目(孤立线段:与其他线段不相交的线段)。

解题策略:还是向量法解决,但是因为溢出的问题,wa了一宿,一度以为算法不严密,大家注意溢出!


/*
   UVA 11343 Isolated Segments
   AC by J_Dark
   ON 2013/5/2 17:09
   Time 0.015s
*/
#include <iostream>
#include <cstdio>
#include <cstring>
#include <cmath>
#include <climits>
#include <vector>
#include <algorithm>
using namespace std;
//int wa, double wa, long long int AC!!!!!!!!!尼玛呀!!!昨晚纠结到半夜,还以为算法问题……
typedef long long int LL;

struct point{
	LL x, y;
	point(LL p=0, LL q=0){
		x = p;
		y = q;
	}
};
struct line{
	point a, b;
	line(point x, point y){
		a = x;
		b = y;
	}
};
vector<line> Seg;
int segNum;
//
void Input(){
	Seg.clear();
	LL 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));
	}
}

int Direction(point Pi, point Pj, point Pk){
	return (Pj.x-Pi.x)*(Pk.y-Pi.y)-(Pk.x-Pi.x)*(Pj.y-Pi.y);
	//return (Pk.x-Pi.x)*(Pj.y-Pi.y) - (Pj.x-Pi.x)*(Pk.y-Pi.y);
}

//判断pk点是否在线段pi-pj上
bool OnSegment(point Pi, point Pj, point Pk){
	if(min(Pi.x, Pj.x) <= Pk.x && max(Pi.x, Pj.x) >= Pk.x &&
	   min(Pi.y, Pj.y) <= Pk.y && max(Pi.y, Pj.y) >= Pk.y)
	   return true;
	return false;
}
//判断线段p,q是否相交
bool isIntersect(line p, line q){
  LL 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 if(d1==0 && OnSegment(p.a, p.b, q.a))  {return true;}
  else if(d2==0 && OnSegment(p.a, p.b, q.b))  {return true;}
  else if(d3==0 && OnSegment(q.a, q.b, p.a))  {return true;}
  else if(d4==0 && OnSegment(q.a, q.b, p.b))  {return true;}
  else return false;
}

void Compute(){
	int ansNum = 0, ff;
	for(int i=0; i<segNum; i++){
	    ff = 0;
		for(int k=0; k<segNum; k++){
			if(i != k){
			   if(isIntersect(Seg[i], Seg[k])){
			      ff = 1;
			      break;
			   }
			}
		}
	    if(!ff)
		   ansNum++;
	}
	cout << ansNum << endl;
}
//
int main(){
	int testCase;
	while(cin >> testCase)
	{
		while(testCase--)
		{
			Input();
			Compute();
			//Output();
		}
	}
	return 0;
}


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 3
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值