POJ3304 Segments

嘟嘟嘟


题面就不说了,网上都有。


刚开始理解成了只要有不孤立的线段就算合法,结果就不会了……然而题中要求是所有线段至少有一个交点。
其实想一想就知道,问题转化为了是否存在一条直线和所有线段都有交点。
所以枚举线段的端点构成直线,然后判断直线和线段是否有交点。
具体做法就是对于直线(AB),判断线段(CD)是否在(AB)的两侧,用叉积即可:如果又向面积符号相同,就说明在一侧,即((overrightarrow{AB} imes overrightarrow{AC}) * (overrightarrow{AB} imes overrightarrow{AD}) >= 0)。一定要包含等于(0)的情况,这样就不用特判平行和重合的情况。
别忘了还得特判选取的两点是否重合。

#include<cstdio>
#include<iostream>
#include<cmath>
#include<algorithm>
#include<cstring>
#include<cstdlib>
#include<cctype>
#include<vector>
#include<stack>
#include<queue>
using namespace std;
#define enter puts("") 
#define space putchar(' ')
#define Mem(a, x) memset(a, x, sizeof(a))
#define rg register
typedef long long ll;
typedef double db;
const int INF = 0x3f3f3f3f;
const db eps = 1e-8;
const int maxn = 505;
inline ll read()
{
  ll ans = 0;
  char ch = getchar(), last = ' ';
  while(!isdigit(ch)) {last = ch; ch = getchar();}
  while(isdigit(ch)) {ans = (ans << 1) + (ans << 3) + ch - '0'; ch = getchar();}
  if(last == '-') ans = -ans;
  return ans;
}
inline void write(ll x)
{
  if(x < 0) x = -x, putchar('-');
  if(x >= 10) write(x / 10);
  putchar(x % 10 + '0');
}

int n;
struct Vec
{
  db x, y;
  db operator * (const Vec& oth)const
  {
    return x * oth.y - oth.x * y;
  }
};
struct Point
{
  db x, y;
  Vec operator - (const Point& oth)const
  {
    return (Vec){x - oth.x, y - oth.y};
  }
}a[maxn], b[maxn];

bool judge(Point A, Point B)
{
  Vec AB = B - A;
  if(fabs(A.x - B.x) < eps && fabs(A.y - B.y) < eps) return 0;
  for(int i = 1; i <= n; ++i)
    {
      Vec AC = a[i] - A, AD = b[i] - A;
      if((AB * AC) * (AB * AD) > eps) return 0;
    }
  return 1;
}

int main()
{
  int T = read();
  while(T--)
    {
      n = read();
      for(int i = 1; i <= n; ++i) 
	scanf("%lf%lf%lf%lf", &a[i].x, &a[i].y, &b[i].x, &b[i].y);
      bool flg = 0;
      if(n < 3) flg = 1;
      for(int i = 1; i < n && !flg; ++i)
	{
	  flg = 0;
	  for(int j = i + 1; j <= n && !flg; ++j)
	    {
	      if(judge(a[i], a[j])) flg = 1;
	      else if(judge(a[i], b[j])) flg = 1;
	      else if(judge(b[i], a[j])) flg = 1;
	      else if(judge(b[i], b[j])) flg = 1;
	    }
	}
      puts(flg ? "Yes!" : "No!");
    }
  return 0;
}
原文地址:https://www.cnblogs.com/mrclr/p/9977233.html