Convex(扫描线降维)
2015-07-30 10:48
204 查看
Convex
Time Limit: 10000/4000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)Total Submission(s): 1838 Accepted Submission(s): 552
[align=left]Problem Description[/align]
Your task is very simple. You will get the coordinates of n points in a plane. It is guaranteed that there are no three points on a straight line. You can choose any four points from these points to construct a quadrangle. Now, please tell me how many convex quadrangles you can construct.
[align=left]Input[/align]
The first line of input contain an integer z (z ≤ 20), indicating the number of test cases.
For each test case, the first line contain an integer n (4 ≤ n ≤ 700), indicating the number of points. Each of the next n lines contains two integers x and y (-1000000 ≤ x, y ≤ 1000000), indicating the coordinate of corresponding point.
[align=left]Output[/align]
For each test case, just output a single integer, the number of convex quadrangles you can construct.
[align=left]Sample Input[/align]
2
4
0 0
0 1
1 0
1 1
4
0 0
1 0
0 1
-1 -1
[align=left]Sample Output[/align]
1
0
题意:给出700个点,求可以构成多少个凸四边形,如果暴力的话肯定会超时
那么可以逆向思维,C4n 个四边形减去凹四边形即可
只要一个三角形中有一个点就是一个凹四边形,但是暴力找三角形照样会超时
那么久找一个点在多少个三角形中和最后统计的每个三角形中的点数的总数是一样的
要想找一个点在多少个三角形中就可以找一个点没在多少个三角形中然后C3n个总共的三角形减去这个值即可
用扫描线法找到其不再多少个三角形的时候,只要枚举每个点,以这个点为中心点的话,和其他每个点连线,找这个线的一侧的点数j , 其上面任选两个点即可构成一个不包含它的三角形
所以就可以C2j 个三角形不包含它,所以先以中心点,将其他点按犄角排序,然后开始逆时针扫描另一侧不用扫描因为在线在转的时候回有扫到下侧的点的,要是考虑两侧的话所有的三角形会被算两遍,这样 枚举中心点是n 的复杂度,每次排序是logn 统计数目又是找点又是n 的,所以最后的复杂度就是n*(logn+n) 这样就不会超时了,起到了降维的作用
下面是代码:
#include <cstdio> #include <cmath> #include <algorithm> using namespace std; #define eps 1e-8 #define pi acos(-1.0) #define N 750 int n; struct point { double x, y; point(){} point(double _x, double _y ):x(_x), y(_y){} }; point P ; double ang[2*N]; int main() { //printf("%d", 700*699*698/6); int T, n; scanf("%d", &T); while(T--) { scanf("%d", &n); for(int i = 0; i < n; i++) scanf("%lf %lf", &P[i].x, &P[i].y); long long ans = (long long)n*(n-1)*(n-2)*(n-3)/24;//C(n,4) for(int i = 0; i < n; i++) { long long cnt = (long long)(n-1)*(n-2)*(n-3)/6;//cnt记录包含i的三角形个数 int c = 0; for(int j = 0; j < n; j++) { if(i == j) continue; ang[c++] = atan2(P[j].y-P[i].y, P[j].x - P[i].x); } sort(ang, ang+c); for(int j = c; j < 2*c; j++) { ang[j] = ang[j-c] + 2*pi; // printf("a-- %lf\n", ang[j-c] * 180.0 /pi); } // puts(""); int k = 1; //puts("haha");while(t < 1000000000) t++; for(int j = 0; j < c; j++)//不包含i的三角形 { while(ang[k] - ang[j] < pi) k++; int d = k-j-1; // printf("d = %d\n", d); if(d > 1) cnt -= d*(d-1)/2; } ans -= cnt; } printf("%I64d\n",ans); } return 0; }
相关文章推荐
- 从头开始写项目Makefile(三):变量的使用
- PullScrollView源码解析
- 用javascript预加载图片、css、js的方法研究
- 机房收费系统——宏观把控
- js 对象深复制,创建对象和继承
- 文件读写——以字符方式读取与写入文件
- org.hibernate.MappingException: An association from the table tuser refers to an unmapped c
- 除非另外还指定了 TOP 或 FOR XML,否则,ORDER BY 子句在视图、内联函数、派生表、子查询和公用表表达式中无效
- 队列复习篇之顺序存储结构
- csu 1548 Road And Bridge
- HDU 2094 产生冠军(STL 集合set)
- POJ_2260_ErrorCorrection
- 收藏
- 使用velocity.js制作炫酷滚动效果页面
- dicom格式文件 界定标识符的处理
- mysql 单机同版本多实例 mysql55
- 深入理解hash长度扩展攻击
- HDU 1300 POJ 1260 Pearls (DP)
- Java 实现基本的排序算法
- IOS中使用像素位图(CGImageRef)对图片进行处理