650.计算几何-选房子 (10分)
C时间限制:3000 毫秒 | C内存限制:3000 Kb
题目内容:
某地有n个房子,法墨的钱可以买三栋。地面上分布着m个金矿,这三栋房子为顶点构成的三角形地面上的金矿都归
法墨。法墨只想要奇数个金矿。他想知道他有多少种选择。
输入描述
可能有多个测试用例。
每个测试用例的第一行是n,m,然后下面n行是n个房子的坐标,再下面m行是m个金矿的坐标。
假设这些坐标中,没有任何三个点是共线的。
输出描述
每个测试用例输出一行,即法墨的选择方案数
输入样例
4 4
-10 0
10 0
0 10
0 -10
1 1
1 2
-1 1
-1 -1
输出样例
2
#include <stdio.h>
#include <math.h>
#define maxn 10005
typedef struct point
{
float x;
float y;
}point;
float S(point a, point b, point c)
{
float s;
point m, n;
m.x = b.x - a.x;
m.y = b.y - a.y;
n.x = c.x - a.x;
n.y = c.y - a.y;
s = fabs((m.x*n.y - n.x*m.y)/2);
// printf("s = %f\n", s);
return s;
}
int main()
{
int n, m, i, j, k, l,count = 0,ans=0;
float area;
point d[maxn], s[maxn];
while((scanf("%d%d",&n,&m)) != EOF)
{
for(i=1; i<=n; i++)
scanf("%f%f", &d[i].x, &d[i].y);
for(i=1; i<=m; i++)
scanf("%f%f", &s[i].x, &s[i].y);
}
for(i=1; i<=n-2; i++)
{
for(j=i+1; j<=n-1; j++)
{
for(k=j+1; k<=n; k++)
{
area = S(d[i], d[j], d[k]);
for(l=1; l<=m; l++)
{
if((S(s[l],d[i],d[j])+S(s[l],d[j],d[k])+S(s[l],d[k],d[i])) == area)
{
count++;
}
}
if(count%2)
ans++;
count = 0;
}
}
}
printf("%d",ans);
return 0;
}
我今天居然写了一个四重循环,我觉得徐老师看到可能要被我气死,哈哈哈哈,想到就莫名开心。。。。
但是其实还是很有纪念意义的,毕竟这是我第一次真正意义上做出来了校OJ上的题目,嗯。。。非常有意义!
简单说一下原理吧,如果点在三角形内部,那么利用叉乘算出其面积就等于三角形的面积,如果点在三角形外部就不等于,这里用到fabs()函数是因为不管点在三角形内部还是外部,利用叉乘算出来的面积都是一样的,但是,加一个绝对值就不一样了。