2 条题解
-
0
#include <iostream> #include <cstring> #include <algorithm> #include <cmath> #define x first #define y second using namespace std; typedef pair<double, double> Point; const int N = 55; const double eps = 1e-8; const double PI = acos(-1.0); int n; double R; Point p[N], o; // 顶点和圆心 Point operator+(Point a, Point b) { // 向量+ return Point(a.x + b.x, a.y + b.y); } Point operator-(Point a, Point b) { // 向量- return Point(a.x - b.x, a.y - b.y); } Point operator*(Point a, double t) { // 数乘 return Point(a.x * t, a.y * t); } Point operator/(Point a, double t) { // 数除 return Point(a.x / t, a.y / t); } double operator*(Point a, Point b) { // 叉积 return a.x * b.y - a.y * b.x; } double operator&(Point a, Point b) { // 点积 return a.x * b.x + a.y * b.y; } double len(Point a) { // 模长 return sqrt(a & a); } double dis(Point a, Point b) { // 距离 return len(b - a); } Point getNode(Point a, Point u, Point b, Point v) { // 直线交点 double t = (a - b) * v / (v * u); return a + u * t; } Point rotate(Point a, double b) { // 逆转角 return Point(a.x * cos(b) - a.y * sin(b), a.x * sin(b) + a.y * cos(b)); } bool onSegment(Point p, Point a, Point b) { // p在线段ab上 return fabs((a - p) * (b - p)) < eps && ((a - p) & (b - p)) <= 0; } Point norm(Point a) { // 单位向量 return a / len(a); } void getDP2(Point a, Point b, Point &pa, Point &pb, double &d) { Point e = getNode(a, b - a, o, rotate(b - a, PI / 2)); // 垂足 d = dis(o, e); if (!onSegment(e, a, b)) d = min(dis(o, a), dis(o, b)); if (R <= d) return; // d:圆心到线段的最近距离 double len = sqrt(R * R - dis(o, e) * dis(o, e)); pa = e + norm(a - b) * len; pb = e + norm(b - a) * len; // pa,pb:线段与圆的两交点 } double sector(Point a, Point b) { // 扇形面积 double angle = acos((a & b) / len(a) / len(b)); //[0,Pi] if (a * b < 0) angle = -angle; return R * R * angle / 2; } double getArea(Point a, Point b) { // 面积的交 if (fabs(a * b) < eps) return 0; // 共线 double da = dis(o, a), db = dis(o, b); if (R >= da && R >= db) return a * b / 2; // ab在圆内 Point pa, pb; double d; getDP2(a, b, pa, pb, d); if (R <= d) return sector(a, b); // ab在圆外 if (R >= da) return a * pb / 2 + sector(pb, b); // a在圆内 if (R >= db) return sector(a, pa) + pa * b / 2; // b在圆内 return sector(a, pa) + pa * pb / 2 + sector(pb, b); // ab是割线 } int main() { while (scanf("%lf%d", &R, &n) != -1) { for (int i = 0; i < n; i++) scanf("%lf%lf", &p[i].x, &p[i].y); double res = 0; for (int i = 0; i < n; i++) res += getArea(p[i], p[(i + 1) % n]); printf("%.2lf\n", fabs(res)); // 点可能顺时针 } return 0; } -
0
#include <iostream> #include <cstring> #include <algorithm> #include <cmath> #define x first #define y second using namespace std; typedef pair<double, double> Point; const int N = 55; const double eps = 1e-8; const double PI = acos(-1.0); int n; double R; Point p[N], o; // 顶点和圆心 Point operator+(Point a, Point b) { // 向量+ return Point(a.x + b.x, a.y + b.y); } Point operator-(Point a, Point b) { // 向量- return Point(a.x - b.x, a.y - b.y); } Point operator*(Point a, double t) { // 数乘 return Point(a.x * t, a.y * t); } Point operator/(Point a, double t) { // 数除 return Point(a.x / t, a.y / t); } double operator*(Point a, Point b) { // 叉积 return a.x * b.y - a.y * b.x; } double operator&(Point a, Point b) { // 点积 return a.x * b.x + a.y * b.y; } double len(Point a) { // 模长 return sqrt(a & a); } double dis(Point a, Point b) { // 距离 return len(b - a); } Point getNode(Point a, Point u, Point b, Point v) { // 直线交点 double t = (a - b) * v / (v * u); return a + u * t; } Point rotate(Point a, double b) { // 逆转角 return Point(a.x * cos(b) - a.y * sin(b), a.x * sin(b) + a.y * cos(b)); } bool onSegment(Point p, Point a, Point b) { // p在线段ab上 return fabs((a - p) * (b - p)) < eps && ((a - p) & (b - p)) <= 0; } Point norm(Point a) { // 单位向量 return a / len(a); } void getDP2(Point a, Point b, Point &pa, Point &pb, double &d) { Point e = getNode(a, b - a, o, rotate(b - a, PI / 2)); // 垂足 d = dis(o, e); if (!onSegment(e, a, b)) d = min(dis(o, a), dis(o, b)); if (R <= d) return; // d:圆心到线段的最近距离 double len = sqrt(R * R - dis(o, e) * dis(o, e)); pa = e + norm(a - b) * len; pb = e + norm(b - a) * len; // pa,pb:线段与圆的两交点 } double sector(Point a, Point b) { // 扇形面积 double angle = acos((a & b) / len(a) / len(b)); //[0,Pi] if (a * b < 0) angle = -angle; return R * R * angle / 2; } double getArea(Point a, Point b) { // 面积的交 if (fabs(a * b) < eps) return 0; // 共线 double da = dis(o, a), db = dis(o, b); if (R >= da && R >= db) return a * b / 2; // ab在圆内 Point pa, pb; double d; getDP2(a, b, pa, pb, d); if (R <= d) return sector(a, b); // ab在圆外 if (R >= da) return a * pb / 2 + sector(pb, b); // a在圆内 if (R >= db) return sector(a, pa) + pa * b / 2; // b在圆内 return sector(a, pa) + pa * pb / 2 + sector(pb, b); // ab是割线 } int main() { while (scanf("%lf%d", &R, &n) != -1) { for (int i = 0; i < n; i++) scanf("%lf%lf", &p[i].x, &p[i].y); double res = 0; for (int i = 0; i < n; i++) res += getArea(p[i], p[(i + 1) % n]); printf("%.2lf\n", fabs(res)); // 点可能顺时针 } return 0; }
- 1
信息
- ID
- 7213
- 时间
- 1000ms
- 内存
- 128MiB
- 难度
- 10
- 标签
- 递交数
- 2
- 已通过
- 1
- 上传者