ASC7 Problem F. Little Mammoth

题目大意

求矩形和圆的交

简要题解

嚯嚯嚯,我会暴力积分!

调了一整天参数,Wrong Answer on Test 2.

爆粗口了,真是没办法,谁叫我弱呢。。

老老实实写精确做法吧。

其实要求的就是三角形和圆的交嘛,9种情况全部讨论一下就好~

啊摔!去你大爷的,你知道这有多难写吗??

有向面积大法好~

来看三张图就明白了~

来源地址

然后就愉快地写呗~

好久没写计算几何了,不过好像我都会实现欸。

然后写完了,好开心~

然后对拍,拍一次错一次,爆粗口×2

要知道我为这道傻缺题已经花了两天了。

血的教训:计算几何千万不要觉得是对的就写,细节会让你明白,你写的全是错的。

所以,有板子就上板子,现推什么的出错的概率太高了。

写完后我发现,这道题我写的调试代码长度是源代码长度的两倍。。爆粗口×3

最坑的地方就是有相交时的处理,GeoGebra是个好软件,可也架不住我个智障选手啊。。

拍了n次,画了n张图,然后发现愚蠢的错误爆n次粗口,然后在图书馆众目睽睽之下抽自己n次耳光。

终于Accept了~ 

  1 #include <bits/stdc++.h>
  2 using namespace std;
  3 namespace my_header {
  4 #define pb push_back
  5 #define mp make_pair
  6 #define pir pair<int, int>
  7 #define vec vector<int>
  8 #define pc putchar
  9 #define clr(t) memset(t, 0, sizeof t)
 10 #define pse(t, v) memset(t, v, sizeof t)
 11 #define bl puts("")
 12 #define wn(x) wr(x), bl
 13 #define ws(x) wr(x), pc(' ')
 14     const int INF = 0x3f3f3f3f;
 15     typedef long long LL;
 16     typedef double DB;
 17     inline char gchar() {
 18         char ret = getchar();
 19         for(; (ret == '\n' || ret == '\r' || ret == ' ') && ret != EOF; ret = getchar());
 20         return ret; }
 21     template<class T> inline void fr(T &ret, char c = ' ', int flg = 1) {
 22         for(c = getchar(); (c < '0' || '9' < c) && c != '-'; c = getchar());
 23         if (c == '-') { flg = -1; c = getchar(); }
 24         for(ret = 0; '0' <= c && c <= '9'; c = getchar())
 25             ret = ret * 10 + c - '0';
 26         ret = ret * flg; }
 27     inline int fr() { int t; fr(t); return t; }
 28     template<class T> inline void fr(T&a, T&b) { fr(a), fr(b); }
 29     template<class T> inline void fr(T&a, T&b, T&c) { fr(a), fr(b), fr(c); }
 30     template<class T> inline char wr(T a, int b = 10, bool p = 1) {
 31         return a < 0 ? pc('-'), wr(-a, b, 0) : (a == 0 ? (p ? pc('0') : p) : 
 32             (wr(a/b, b, 0), pc('0' + a % b)));
 33     }
 34     template<class T> inline void wt(T a) { wn(a); }
 35     template<class T> inline void wt(T a, T b) { ws(a), wn(b); }
 36     template<class T> inline void wt(T a, T b, T c) { ws(a), ws(b), wn(c); }
 37     template<class T> inline void wt(T a, T b, T c, T d) { ws(a), ws(b), ws(c), wn(d); }
 38     template<class T> inline T gcd(T a, T b) {
 39         return b == 0 ? a : gcd(b, a % b); }
 40     template<class T> inline T fpw(T b, T i, T _m, T r = 1) {
 41         for(; i; i >>= 1, b = b * b % _m)
 42             if(i & 1) r = r * b % _m;
 43         return r; }
 44 };
 45 using namespace my_header;
 46 
 47 
 48 const DB PI = 3.1415926535897932384626;
 49 const DB EPS = 1e-6;
 50 int sgn(DB x) {
 51     return x < -EPS ? -1 : EPS < x;
 52 }
 53 
 54 #define Vector Point
 55 struct Point {
 56     DB x, y;
 57     Point() {}
 58     Point(DB x, DB y):x(x), y(y) {}
 59     Vector operator + (Vector);
 60     Vector operator - (Vector);
 61     Vector operator * (DB);
 62     Vector operator / (DB);
 63     DB getCross(Vector);
 64     DB getDot(Vector);
 65     DB getLength();
 66     DB getAngle(Vector);
 67     Vector getNorm();
 68     Vector Rotate(DB);
 69 };
 70 
 71     
 72 struct Circle {
 73     Point o;
 74     DB r;
 75     DB getSectorArea(DB);
 76     vector<Point> getSegmentIntersection(Point, Point);
 77 };
 78 
 79 DB getSegmentCirlcleProjectionArea(Circle, Point, Point);
 80 DB getTriangleCircleIntersectionArea(Circle, Point, Point, Point);
 81 bool onSegment(Point, Point, Point);
 82 
 83 int main() {
 84 #ifdef lol
 85     freopen("F.in", "r", stdin);
 86     freopen("F.out", "w", stdout);
 87 #else
 88     freopen("mammoth.in", "r", stdin);
 89     freopen("mammoth.out", "w", stdout);
 90 #endif
 91 
 92     Circle c;
 93     Point a, b;
 94     cin >> c.o.x >> c.o.y >> c.r;
 95     cin >> a.x >> a.y;
 96     cin >> b.x >> b.y;
 97     if (b.x < a.x) swap(a.x, b.x);
 98     if (b.y < a.y) swap(a.y, b.y);
 99 
100     DB ans = 0;
101     ans += getTriangleCircleIntersectionArea(c, a, Point(a.x, b.y), b);
102     ans += getTriangleCircleIntersectionArea(c, a, Point(b.x, a.y), b);
103     printf("%.8lf\n", ans);
104     return 0;
105 }
106 
107 DB getSegmentCirlcleProjectionArea(Circle C, Point a, Point b) {
108     vector<Point> t = C.getSegmentIntersection(a, b);
109     if (t.size() == 0) {
110         if ((a - C.o).getLength() < C.r + EPS && (b - C.o).getLength() < C.r + EPS)
111             return (a - C.o).getCross(b - C.o) / 2;
112         return C.getSectorArea((a - C.o).getAngle(b - C.o));
113     }
114     if (t.size() == 1) {
115         Point c = t.at(0);
116         if ((a - C.o).getLength() <= C.r) {
117             return C.getSectorArea((c - C.o).getAngle(b - C.o)) + (a - C.o).getCross(c - C.o) / 2;
118         }
119         else {
120             return C.getSectorArea((a - C.o).getAngle(c - C.o)) + (c - C.o).getCross(b - C.o) / 2;
121         }
122     }
123     return C.getSectorArea((a - C.o).getAngle(t[0] - C.o)) + (t[0] - C.o).getCross(t[1] - C.o) / 2 + C.getSectorArea((t[1] - C.o).getAngle(b - C.o));
124 }
125 
126 DB getTriangleCircleIntersectionArea(Circle C, Point a, Point b, Point c) {
127     DB res = 0;
128     res += getSegmentCirlcleProjectionArea(C, a, b);
129     res += getSegmentCirlcleProjectionArea(C, b, c);
130     res += getSegmentCirlcleProjectionArea(C, c, a);
131     return fabs(res);
132 }
133 
134 Vector Vector::operator + (Vector b) {
135     return Vector(x + b.x, y + b.y);
136 }
137 Vector Vector::operator - (Vector b) {
138     return Vector(x - b.x, y - b.y);
139 }
140 Vector Vector::operator * (DB b) {
141     return Vector(x * b, y * b);
142 }
143 Vector Vector::operator / (DB b) {
144     return Vector(x / b, y / b);
145 }
146 DB Vector::getCross(Vector b) {
147     return x * b.y - y * b.x;
148 }
149 DB Vector::getDot(Vector b) {
150     return x * b.x + y * b.y;
151 }
152 DB Vector::getLength() {
153     return sqrt(this->getDot(*this));
154 }
155 Vector Vector::Rotate(DB ang) {
156     DB c = cos(ang), s = sin(ang);
157     return Vector(c * x - s * y, s * x + c * y);
158 }
159 Vector Vector::getNorm() {
160     DB l = this->getLength();
161     return Vector(x / l, y / l);
162 }
163 DB Vector::getAngle(Vector b) {
164     DB t = atan2(b.y, b.x) - atan2(y, x);
165     while (t > PI)
166         t -= 2 * PI;
167     while (t < -PI)
168         t += 2 * PI;
169     return t;
170 }
171 
172 bool onSegment(Point a, Point b, Point c) {
173     return sgn((c - a).getDot(b - a)) > 0 && sgn((c - b).getDot(a - b)) > 0;
174 }
175 
176 DB Circle::getSectorArea(DB ang) {
177     return ang * r * r / 2;
178 }
179 vector<Point> Circle::getSegmentIntersection(Point a, Point b) {
180     vector<Point> res;
181     Point p = a + (b - a).getNorm() * (b - a).getDot(o - a) / (b - a).getLength();
182     if ((p - o).getLength() >= r)
183         return res;
184     DB d = sqrt(r * r - (p - o).getDot(p - o));
185     Vector tmp = (b - a).getNorm() * d;
186     if (onSegment(a, b, p - tmp))
187         res.push_back(p - tmp);
188     if (onSegment(a, b, p + tmp))
189         res.push_back(p + tmp);
190     return res;
191 }

 

 

 

 

posted @ 2017-02-19 19:16  ichneumon  阅读(216)  评论(0编辑  收藏  举报