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