HDU 1086 You can Solve a Geometry Problem too [计算几何]

#Description
给N条线段,求交点个数,如果重合,算两个
#Algorithm
简直模板
首先我参考
《挑战程序设计竞赛》发现了一个方法,不过书上说还有一个别的方法,ccw函数
这里写图片描述
字有点歪,不管了

然后我百度良久,都没有看到什么是CCW
好在还有谷歌
于是就查到了
6.1 Geometric Primitives
虽然是JAVA写的,好在还是比较好读,改一下就变成C++的。
然后这个算法应该是出自《算法(第四版)》,以后去查查
当然了,目前还不知道为什么这样可以,待学习
#Hint
对于此题,要把ccw的int改成double,我就是因此WA了几次
#Code

#include <iostream>
using namespace std;
const int maxn = 100 + 9;
int n;
struct P
{
  double x, y;
};
struct Segment
{
  P p, q;
};
double ccw(P a, P b, P c)
{
   return (b.x - a.x) * (c.y - a.y) - (c.x - a.x) * (b.y - a.y);
}
bool intersects(Segment a, Segment b)
{
   if (ccw(a.p, a.q, b.p) * ccw(a.p, a.q, b.q) > 0) return false;
   if (ccw(b.p, b.q, a.p) * ccw(b.p, b.q, a.q) > 0) return false;
   return true;
}
Segment a[maxn];
void solve()
{
  for (int i = 0; i < n; i++)
  {
    P p0, p1;
    cin >> a[i].p.x >> a[i].p.y >> a[i].q.x >> a[i].q.y;
  }
  int ans = 0;
  for (int i = 0; i < n; i++)
    for (int j = 0; j < i; j++)
    if (intersects(a[i], a[j])) ans++;
  cout << ans << endl;
}
int main()
{
  for (;;)
  {
    cin >> n;
    if (n == 0) break;
    solve();
  }
}

猜你喜欢

转载自blog.csdn.net/YYecust/article/details/50936655