【计蒜客】红黑点
来源:互联网 发布:linux 文件改名字 编辑:程序博客网 时间:2024/04/25 08:52
题目
在二维平面有 n 个红点和 m 个黑点,已知这些点的坐标,这些点不存在三点共线的情况。从这些红点中任意取出三个点,可以构成 n * ( n - 1 ) * ( n - 2 ) / 6 个三角形,求这些三角形中包含黑点的数量为奇数的三角形的数量。
输入格式
输入包含多组测试数据,对于每组测试数据:
第一行包含两个整数 n m ( 3 ≤ n ≤ 100 ; 0 ≤ m ≤ 1000 ) 。
接下来 n 行每行包含两个整数,表示 n 个红点的坐标。
接下来 m 行每行包含两个整数,表示 m 个黑点的坐标。
输入保证所有的坐标值的绝对值小于等于 100000 。
输出格式
对于每组测试数据,输出 “Case c: ans” ,其中 c 表示测试数据编号, ans 表示包含奇数个黑点的三角形的数量。
样例输入
4 5
0 0
10 0
0 10
10 10
1 2
3 4
6 2
9 5
6 7
样例输出
Case 1: 2
思路
根据题目所说我们将所有的红色点都将构成三角形并且我们判断黑色的点是否在三角形内部,然后我们转化如何判断点在三角形内部;
根据数学知识叉乘发来判断点是否在三角形内部
叉乘法
沿着三角形的边按顺时针方向走,判断该点是否在每条边的右边(这可以通过叉乘判断),如果该点在每条边的右边,则在三角形内,否则在三角形外。这个算法只用到了三次叉乘,没有除法运算和三角函数、开根号等运算,所以效率很高,而且精度很高(没有浮点误差)。
即(x1*y2-x2*y1)
设三角形三点A(x1,y1)B(x2,y2)C(x3,y3),已知点M(x,y)
1,先求出三个向量MA,MB,MC.
2,计算MA X MB,MB X MC,MC X MA (X表叉乘)
3,如果此三组的向量叉乘的结果都是同号的(或都正,或都负),即方向相同的,则说明点M在三角形每条边的同侧,即内部。否则必在外部!
具体示例:
A(0,3) B(0,0) C(3,0)
M(1,1)
MA (1,-2)
MB (1,1)
MC (-2,1)
MA X MB = 3
MB X MC = 3
MC X MA = 3
N(3,3)
NA (3,0)
NB (3,3)
NC (0,3)
NA X NB = 9
NB X NC = 9
NC X NA = -9
根据以上规则可判断M点在内 N点在外
下面引入代码
代码
#include<iostream>using namespace std;#define maxn 1000static int cc = 0;int n, m;struct point //点创建{ float x, y;}p[maxn], b[maxn];bool IsInPology(point xx, point yy, point zz, point b)//判断点是否在内部 x,y,z分别表示三个点,b[]表示黑色点的数据{ point bx, by, bz; bx.x = b.x - xx.x; bx.y = b.y - xx.y; by.x = b.x - yy.x; by.y = b.y - yy.y; bz.x = b.x - zz.x; bz.y = b.y - zz.y; float t1, t2, t3;//叉乘法 t1 = bx.x*by.y - bx.y*by.x; t2 = by.x*bz.y - by.y*bz.x; t3 = bz.x*bx.y - bz.y*bx.x; if ((t1 >= 0 && t2 >= 0 && t3 >= 0) || (t1 <= 0 && t2 <= 0 && t3 <= 0))return true; else return false;}//是否具有奇数个黑色的点bool IsOd(point x, point y, point z, point b[]){ int cnt = 0;//计数器统计黑色点的数量 for (int i = 0; i<m; i++) { if (IsInPology(x, y, z, b[i]) == true)cnt++; } if (cnt % 2 == 0)return false; return true;}int main(){ cin >> n >> m; //红色的点 n for (int i = 0; i<n; i++) { cin >> p[i].x >> p[i].y; } //黑色的点 m for (int i = 0; i<m; i++) { cin >> b[i].x >> b[i].y; } //取三个点 int numP = n, cnt = 0; for (int i = 0; i < n - 2; i++) { for (int j = i + 1; j < n - 1; j++) { for (int k = j + 1; k < n; k++) { if (IsOd(p[i], p[j], p[k], b) == true)cnt++; } } } cout << "Case "<<++cc<<": " << cnt << endl; return 0;}
转载时,请注明出处,谢谢合作
- 【计蒜客】红黑点
- 要警惕眼睛有红血丝和黑点!
- 红
- 红
- 白板上的黑点
- 数数有几个黑点
- 一张白纸有了一个黑点
- 火狐html显示黑点
- 去除dialog小黑点
- 求网格中的黑点分布
- 消除列表前的黑点
- 红妈咪妈咪红
- 黑白图象中黑点数的计算方法
- word每个标题前都有个小黑点,怎么去掉?
- 导航栏里出现黑点问题
- 去掉office标题前的黑点
- word去除标题前的小黑点
- word标题前的小黑点
- Python sorted 函数
- Spring配置之AOP
- 工作安排(dfs深度优先搜索)
- bzoj2274[Usaco2011 Feb]Generic Cow Protests
- 列最大值与行对角交换
- 【计蒜客】红黑点
- jsp使用include导入html乱码解决
- Spring数据源配置之c3p0
- Spring数据源配置之dpcp
- chrome浏览器跨域设置
- hihoCoder 交错和 (数位DP)
- 瀑布流布局
- 人文名胜与历史文化
- Spring数据源配置之bonecp