有大佬帮忙看看这是为啥吗
查看原帖
有大佬帮忙看看这是为啥吗
274886
daijuruo楼主2021/10/14 11:58

两个代码只改了一行,一个T第一个点一个飞快AC。只改了个判断条件,而且(我认为)这个判断都是O(1)的。

#include<bits/stdc++.h>
using namespace std;
const double eps = 1e-4;
const double inf = 1e18;
const double pi = acos(-1.0);
const int maxp = 20005;

int sgn(double x)//判断正负
{
	if (fabs(x) < eps)return 0;
	if (x < 0)return -1;
	else return 1;

}
inline double sqr(double x) { return x * x; }
struct Point
{
	double x, y;
	Point() {}
	Point(double _x, double _y)
	{
		x = _x;
		y = _y;
	}
	void input()
	{
		scanf("%lf%lf", &x, &y);
	}
	bool operator == (Point b)const
	{
		return sgn(x - b.x) == 0 && sgn(y - b.y) == 0;
	}
	bool operator < (Point b)const
	{
		return sgn(x - b.x) == 0 ? sgn(y - b.y) < 0 : x < b.x;
	}
	Point operator -(const Point& b)const
	{
		return Point(x - b.x, y - b.y);
	}
	double operator ^(const Point& b)const//叉积
	{
		return x * b.y - y * b.x;
	}
	double operator *(const Point& b)const//点积
	{
		return x * b.x + y * b.y;
	}
	double distance(Point p)//返回两点距离 求凸包时Point类只需该函数及以上的函数!
	{
		return hypot(x - p.x, y - p.y);
	}
	double len()//返回长度
	{
		return hypot(x, y);
	}
	Point operator +(const Point& b)const
	{
		return Point(x + b.x, y + b.y);
	}
	Point operator /(const double& k)const
	{
		return Point(x / k, y / k);
	}
	Point rotate(Point p, double angle)//绕着p点逆时针旋转angle弧度
	{
		Point v = (*this) - p;
		double c = cos(angle), s = sin(angle);
		return Point(p.x + v.x * c - v.y * s, p.y + v.x * s + v.y * c);
	}
};
struct Line
{
	Point s, e;
	Line() {};
	Line(Point _s, Point _e)//求凸包时Line类只需该函数及以上的函数!
	{
		s = _s;
		e = _e;
	}
	bool operator == (Line v)
	{
		return(s == v.s) && (e == v.e);
	}
	void input()
	{
		s.input();
		e.input();
	}
	double length()//求线段长度
	{
		return s.distance(e);
	}
	bool pointonseg(Point p)//点在线段上判断
	{
		return sgn((p - s) ^ (e - s)) == 0 && sgn((p - s) * (p - e)) <= 0;
	}
	double dispointtoline(Point p)//点到直线距离
	{
		return fabs((p - s) ^ (e - s)) / length();
	}
	double dispointtoseg(Point p)//点到线段距离
	{
		if (sgn((p - s) * (e - s)) < 0 || sgn((p - e) * (s - e)) < 0)
			return min(p.distance(s), p.distance(e));
		return dispointtoline(p);
	}
};
struct circle
{
	Point p;
	double r;
	circle() {};
	circle(Point _p, double _r)
	{
		p = _p;
		r = _r;
	}
	double area()
	{
		return pi * r * r;
	}
	int relation(Point b)//点和圆关系 0圆外 1圆上 2园内
	{
		double dst = b.distance(p);
		if (sgn(dst - r) < 0)return 2;
		else if (sgn(dst - r) == 0)return 1;
		else return 0;
	}
	int relationseg(Line v)//线段和圆的关系
	{
		double dst = v.dispointtoseg(p);
		if (sgn(dst - r) < 0)return 2;
		else if (sgn(dst - r) == 0)return 1;
		else return 0;
	}
	int relationline(Line v)//直线和圆的关系
	{
		double dst = v.dispointtoline(p);
		if (sgn(dst - r) < 0)return 2;
		else if (sgn(dst - r) == 0)return 1;
		else return 0;
	}
};
struct polygon
{
	int n;
	Point p[maxp];
	Line l[maxp];
	void add(Point q)
	{
		p[n++] = q;
	}
	void getline()
	{
		for (int i = 0; i < n; ++i)
			l[i] = Line(p[i], p[(i + 1) % n]);
	}
	int relationpoint(Point q)//判断点和任意多边形关系 3点上 2边上 1内部 0外部
	{
		for (int i = 0; i < n; i++)
			if (p[i] == q)
				return 3;
		getline();
		for (int i = 0; i < n; i++)
			if (l[i].pointonseg(q))
				return 2;
		int cnt = 0;
		for (int i = 0; i < n; i++)
		{
			int j = (i + 1) % n;
			int k = sgn((q - p[j]) ^ (p[i] - p[j]));
			int u = sgn(p[i].y - q.y);
			int v = sgn(p[j].y - q.y);
			if (k > 0 && u < 0 && v >= 0)cnt++;
			if (k < 0 && v < 0 && u >= 0)cnt--;
		}
		return cnt != 0;
	}
	int relationcircle(circle c)//多边形和圆的关系 2圆完全在多边形内 1圆在多边形内,碰(切)到了多边形边界 0其他
	{
		getline();
		int x = 2;
		if (relationpoint(c.p) != 1)return 0;//圆心不在内部
		for (int i = 0; i < n; ++i)
		{
			if (c.relationseg(l[i]) == 2)return 0;
			if (c.relationseg(l[i]) == 1)x = 1;
		}
		return x;
	}
};

Point p[10], tp;
Line W, R, N, M;
circle C;
polygon G;
double r;

double mj(Point a, Point b, Point c, Point d, int t)
{
	tp = { (a.x + c.x) / 2, (a.y + c.y) / 2 };
	if (C.relation(a) && C.relation(b) && C.relation(c) && C.relation(d))return (a.x - c.x) * (a.x - c.x);
	W = { a,b }; R = { b,c }; N = { c,d }; M = { d,a };
	if (W.dispointtoline(C.p) > r && R.dispointtoline(C.p) > r && N.dispointtoline(C.p) > r && M.dispointtoline(C.p) > r)return 0;
	if (t >= 15 || fabs(a.x - c.x) < 0.02)
	{
		if (C.relation(tp) == 2)return (a.x - c.x) * (a.x - c.x);
		else if (C.relation(tp) == 1)return (a.x - c.x) * (a.x - c.x) / 2;
		else return 0;
	}
	return mj(a, (a + b) / 2, (a + c) / 2, (a + d) / 2, t + 1) + mj((a + b) / 2, b, (b + c) / 2, (a + c) / 2, t + 1) + mj((a + c) / 2, (b + c) / 2, c, (c + d) / 2, t + 1) + mj((a + d) / 2, (a + c) / 2, (c + d) / 2, d, t + 1);
}

int main()
{
	double x, y, xx, yy, xxx, yyy; cin >> x >> y >> xx >> yy >> xxx >> yyy >> r;
	p[0] = Point(xxx, yyy);
	p[1] = Point(x, y);
	p[3] = Point(xx, yy);
	double k = atan2(yy - y, xx - x);
	p[0] = p[0].rotate(Point(0, 0), -k + pi / 4);
	p[1] = p[1].rotate(Point(0, 0), -k + pi / 4);
	p[3] = p[3].rotate(Point(0, 0), -k + pi / 4);
	p[2] = Point(p[3].x, p[1].y);
	p[4] = Point(p[1].x, p[3].y);
	C = circle(p[0], r);
	G.add(p[1]), G.add(p[2]), G.add(p[3]), G.add(p[4]);
	if (G.relationcircle(C) != 0)printf("%.2f", C.area());
	else printf("%.2f", mj(p[1], p[2], p[3], p[4], 0));
}

上面这个吸氧T第一个点,下面跑的飞快,只修改了判断当前递归的正方形是否完全在圆外的那行。

double mj(Point a, Point b, Point c, Point d, int t)
{
	tp = { (a.x + c.x) / 2, (a.y + c.y) / 2 };
	if (C.relation(a) && C.relation(b) && C.relation(c) && C.relation(d))return (a.x - c.x) * (a.x - c.x);
	W = { a,b }; R = { b,c }; N = { c,d }; M = { d,a };
	if (W.dispointtoline(C.p) > r && R.dispointtoline(C.p) > r && N.dispointtoline(C.p) > r && M.dispointtoline(C.p) > r)return 0;
	if (t >= 15 || fabs(a.x - c.x) < 0.02)
	{
		if (C.relation(tp) == 2)return (a.x - c.x) * (a.x - c.x);
		else if (C.relation(tp) == 1)return (a.x - c.x) * (a.x - c.x) / 2;
		else return 0;
	}
	return mj(a, (a + b) / 2, (a + c) / 2, (a + d) / 2, t + 1) + mj((a + b) / 2, b, (b + c) / 2, (a + c) / 2, t + 1) + mj((a + c) / 2, (b + c) / 2, c, (c + d) / 2, t + 1) + mj((a + d) / 2, (a + c) / 2, (c + d) / 2, d, t + 1);
}
2021/10/14 11:58
加载中...