几何计算模板

  1 #include <cstdio>
  2 #include <cstring>
  3 #include <algorithm>
  4 #include <cmath>
  5 #include <vector>
  6 #include <iostream>
  7 #include <cassert>
  8 
  9 using namespace std;
 10 
 11 typedef long long lld;
 12 
 13 const double EPS = 1e-9;
 14 const int MOD = 998244353;
 15 
 16 int sign(double x) {return x < -EPS ? -1 : x > EPS;}
 17 
 18 struct Point {
 19     lld x, y;
 20     Point() {}
 21     Point(const lld &x, const lld &y): x(x), y(y) {}
 22 
 23     void in() {
 24         cin >> x >> y;
 25     }
 26 
 27     bool dim() const {
 28         return x < 0 || x == 0 && y < 0;
 29     }
 30 };
 31 
 32 Point operator + (const Point &a, const Point &b) {
 33     return Point(a.x + b.x, a.y + b.y);
 34 }
 35 Point operator - (const Point &a, const Point &b) {
 36     return Point(a.x - b.x, a.y - b.y);
 37 }
 38 lld operator * (const Point &a, const Point &b) {
 39     return a.x * b.y - a.y * b.x;
 40 }
 41 bool operator < (const Point &a, const Point &b) {
 42     if (a.dim() == b.dim()) {
 43         return a * b > 0;
 44     }else {
 45         return a.dim() > b.dim();
 46     }
 47 }
 48 
 49 typedef vector<Point> Points;
 50 
 51 lld pow_mod(lld x, lld n) {
 52     lld ret = 1;
 53     while (n) {
 54         if (n & 1) ret = ret * x % MOD;
 55         n >>= 1; x = x * x % MOD;
 56     }
 57     return ret;
 58 }
 59 
 60 inline void add(int &x, int ad) {
 61     x += ad;
 62     if (x >= MOD) x -= MOD;
 63 }
 64 
 65 lld area(const Point &a, const Point &b) {
 66     return a * b;
 67 }
 68 
 69 int n, tot;
 70 lld pw2[1005];
 71 Point vec[1005];
 72 
 73 void work() {
 74     scanf("%d", &n);
 75     Points points(n);
 76     for (int i = 0; i < n; i++) {
 77         points[i].in();
 78     }
 79     int ans = 0;
 80     for (int i = 0; i < n; i++) {
 81         tot = 0;
 82         for (int j = 0; j < n; j++) {
 83             if (j == i) continue;
 84             vec[tot ++] = points[j] - points[i];
 85         }
 86         sort(vec, vec + tot);
 87         for (int j = 0; j < tot; j++) {
 88             int l = 1, r = tot - 1;    
 89             while (r >= l) {
 90                 int mid = (r + l) >> 1;
 91                 int Mid = (mid + j) % tot;
 92                 if (vec[j] * vec[Mid] > 0) {
 93                     l = mid + 1;
 94                 }else {
 95                     r = mid - 1;
 96                 }
 97             }
 98             -- l;
 99             add(ans, (area(points[i], points[i] + vec[j]) % MOD * (pw2[l] - 1) % MOD + MOD) % MOD);
100         }
101     }
102     printf("%d\n", ans);
103 }
104 
105 int main() {
106     pw2[0] = 1;
107     for (int i = 1; i <= 1000; i++) {
108         pw2[i] = 2 * pw2[i-1] % MOD;
109     }
110     int T;
111     scanf("%d", &T);
112     for (int cas = 1; cas <= T; cas++) {
113         work();
114     }
115     return 0;
116 }
View Code

 doublle型

  1 #include <cstdio>
  2 #include <cstring>
  3 #include <algorithm>
  4 #include <vector>
  5 #include <cmath>
  6 #include <cassert>
  7 #include <set>
  8 
  9 using namespace std;
 10 
 11 const double Pi = 3.14159265358979324;
 12 const double EPS = 1e-8;
 13 
 14 int sign(double x) {return x < -EPS ? -1 : x > EPS;}
 15 
 16 struct Point {
 17     double x, y;
 18     
 19     Point() {}
 20     Point(const double &x, const double &y): x(x), y(y) {}
 21 
 22     double norm() const {
 23         return sqrt(x * x + y * y);
 24     }
 25 
 26     double ang() const {
 27         return atan2(y, x);
 28     }
 29     
 30     Point util() const {
 31         return Point(x / norm(), y / norm());
 32     }
 33 
 34     void in() {
 35         scanf("%lf%lf", &x, &y);
 36     }
 37 };
 38 
 39 Point operator + (const Point &a, const Point &b) {
 40     return Point(a.x + b.x, a.y + b.y);
 41 }
 42 Point operator - (const Point &a, const Point &b) {
 43     return Point(a.x - b.x, a.y - b.y);
 44 }
 45 Point operator * (const double &b, const Point &a) {
 46     return Point(a.x * b, a.y * b);
 47 }
 48 double operator * (const Point &a, const Point &b) {
 49     return a.x * b.y - a.y * b.x;
 50 }
 51 bool operator < (const Point &a, const Point &b) {
 52     return sign(a.x - b.x) < 0 ||
 53         sign(a.x - b.x) == 0 && sign(a.y - b.y) < 0;
 54 }
 55 bool operator != (const Point &a, const Point &b) {
 56     return sign(a.x - b.x) || sign(a.y - b.y);
 57 }
 58 bool operator == (const Point &a, const Point &b) {
 59     return sign(a.x - b.x) == 0 && sign(a.y - b.y) == 0;
 60 }
 61 
 62 typedef vector<Point> Points;
 63 typedef vector<Point> Convex;
 64 
 65 Point rotate(const Point &a, const double &ang) {
 66     double x = a.x * cos(ang) - a.y * sin(ang);
 67     double y = a.x * sin(ang) + a.y * cos(ang);
 68     return Point(x, y);
 69 }
 70 
 71 int convex_hull(Points &ps, Convex &reg) {
 72     int n = ps.size();
 73     if (n <= 2) {
 74         reg = ps; return n;
 75     }
 76     sort(ps.begin(), ps.end());
 77     reg.resize(n * 2);
 78     int k = 0;
 79     for (int i = 0; i < n; i++) {
 80         while (k > 1 && sign((reg[k-1] - reg[k-2]) * (ps[i] - reg[k-1])) <= 0) -- k;
 81         reg[k ++] = ps[i];
 82     }
 83     for (int i = n - 2, t = k; i >= 0; i--) {
 84         while (k > t && sign((reg[k-1] - reg[k-2]) * (ps[i] - reg[k-1])) <= 0) -- k;
 85         reg[k ++] = ps[i];
 86     }
 87     reg.resize(k - 1);
 88     return reg.size();
 89 }
 90 
 91 struct Line {
 92     Point s, d;
 93     Line() {}
 94     Line(const Point &a, const Point &b): s(a), d(b - a) {}
 95 };
 96 
 97 Point line_line_cross(const Line &a, const Line &b) {
 98     assert(sign(a.d * b.d) != 0);
 99     double lambda(((b.s - a.s) * b.d) / (a.d * b.d));
100     return a.s + lambda * a.d;
101 }
102 
103 struct Circle {
104     Point c;
105     double r;
106     Circle() {}
107     Circle(const Point &a, const double &b): c(a), r(b) {}
108 
109     Point point(const double &ang) const {
110         return Point(c.x + cos(ang) * r, c.y + sin(ang) * r);
111     }
112 
113     double area() const {
114         return r * r * Pi;
115     }
116     double peri() const {
117         return 2 * r * Pi;
118     }
119     
120     void in() {
121         c.in(); scanf("%lf", &r);
122     }
123 };
124 
125 int circle_circle_cross(const Circle &a, const Circle &b, Points &reg) {
126     double d = (a.c - b.c).norm();
127     if (sign(d) == 0) {
128         if (sign(a.r - b.r) == 0) return -1;
129         return 0;
130     }
131     if (sign(a.r + b.r - d) < 0) return 0 ;
132     if (sign(fabs(a.r - b.r) - d) > 0) return 0;
133 
134     double ang = (b.c - a.c).ang();
135     double da = acos((a.r * a.r + d * d - b.r * b.r) / (2 * a.r * d));
136     Point p1 = a.point(ang - da), p2 = a.point(ang + da);
137 
138     reg.push_back(p1);
139     if (p1 == p2) return 1;
140     reg.push_back(p2);
141     return 2;
142 }
143 
144 
145 int main() {
146     return 0;
147 }
View Code

 极角排序

#include<bits/stdc++.h>
using namespace std;
const int M = 2e3 + 10 ;
typedef long long ll ;

int n ;
struct Point {
       int  x , y ;
       Point () {} 
       Point (const int &x , const int &y) :
               x(x) , y(y) {}
       int dim() const {
               return x < 0 || x == 0 && y < 0 ;
       }
       void in () { cin >> x >> y ; }
} a[M] ;
Point b[M] ;
ll tot , cut ;
int operator * (const Point &a , const Point &b) {
        return a.x*b.y - a.y*b.x ;
}

bool operator < (const Point &a, const Point &b) {
    if (a.dim() == b.dim()) {
        return a * b > 0;
    }else {
        return a.dim() > b.dim();
    }
}

bool operator == (const Point &a , const Point &b) {
        return !(a < b) && !(b < a);
}

int main () {
        ios::sync_with_stdio (false) ;
        cin >> n ;
        for (int i = 0 ; i < n ; i ++) a[i].in () ;
        tot = 1ll*n*(n-1)*(n-2) / 6 ;

        for (int i = 0 ; i < n ; i ++) {
                for (int j = 0 , N = 0 ; j < n ; j ++) {
                        if (i == j) continue ;
                        b[N] = Point (a[j].x-a[i].x , a[j].y-a[i].y) ;
                        N ++ ;
                }
                sort (b , b + n-1 ) ;
                int tmp = 0 ;
                for (int j = 1 ; j < n-1 ; j ++) {
                        if (b[j] == b[j-1]) tmp ++ ;
                        else {
                                cut += 1ll * (tmp+1) * tmp / 2 ;
                                tmp = 0 ;
                        }
                }
                cut += 1ll * (tmp+1) * tmp / 2 ;
        }
        cout << tot - cut/2 << endl ;
        return 0 ;
}

恩,碰到有重点的情况,你在结构体里要放上id这个属性,在x,y都相等的时候,再按照id拍个序,不然会出现各种re , tle。

今天2016.7.20打多校,我的同伴们就因为这个原因,卡了很长时间。

额,讲道理,还是要感谢他们检查除了这个bug @仓鼠@幻神。

posted @ 2015-08-16 19:43  92度的苍蓝  阅读(183)  评论(0编辑  收藏  举报
http://images.cnblogs.com/cnblogs_com/Running-Time/724426/o_b74124f376fc157f352acc88.jpg