URL: http://acm.fzu.edu.cn/problem.php?pid=2148
PS: 枚举所以四个点的情况,判断是为凸四边形,判断方法是求解一次凸包。
#include <iostream> #include <cstdio> #include <cstring> #include <algorithm> #include <cmath> const int maxn = 40; using namespace std; //Accepted 2148 GNU C++ 656 ms 228KB 2154B achiberx struct point { int x, y; point(int a=0, int b=0):x(a), y(b){} int operator^(const point &op) const { return x*op.y - y*op.x; } }; point p[maxn]; int n; point tmp[8]; point p0; int sqr(int x) { return x*x; } int dis2(point p0, point p1) { return sqr(p0.x-p1.x)+sqr(p0.y-p1.y); } point operator - (point A, point B) { return point(A.x-B.x, A.y-B.y); } int mul(point p0, point p1, point p2) { return (p1-p0)^(p2-p0); } bool cmp(point a, point b) { if(mul(p0, a, b)>0 || (mul(p0, a, b)==0 && dis2(p0, a)<dis2(p0,b))) return true; return false; } point q[8]; bool work(point a, point b, point c, point d) { tmp[0] = a, tmp[1]=b, tmp[2]=c, tmp[3]=d; for(int i = 1; i < 4; i++) { if(tmp[i].x-tmp[0].x<0 || (tmp[i].x-tmp[0].x==0 && tmp[i].y-tmp[0].y<0)) { swap(tmp[0], tmp[i]); } } p0 = tmp[0]; sort(tmp, tmp+4, cmp); int newn = 2; q[0]=tmp[0], q[1] = tmp[1]; for(int i = 2; i < 4; ++i) { while(newn>1 && mul(q[newn-1], q[newn-2], tmp[i])>=0) --newn; q[newn++] = tmp[i]; } if(newn==4) return true; else return false; } int main() { int T; int cnt = 0; scanf("%d", &T); for(int t = 1; t <= T; t++) { scanf("%d", &n); for(int i = 0; i < n; i++) { scanf("%d%d", &p[i].x, &p[i].y); } cnt = 0; if(n<=3) { printf("Case %d: %d\n", t, cnt); continue; } for(int i = 0; i < n; i++) { for(int j = i+1; j < n; j++) { for(int k = j+1; k < n; k++) { for(int q = k+1; q < n; q++) { bool res = work(p[i], p[j], p[k], p[q]); if(res) cnt++; } } } } printf("Case %d: %d\n", t, cnt); } return 0; }
FZU 2148 Moon Game,布布扣,bubuko.com
原文地址:http://blog.csdn.net/achiberx/article/details/25335823