QOJ.ac

QOJ

ID题目提交者结果用时内存语言文件大小提交时间测评时间
#451137#6831. Known as the Fruit BrotherPetroTarnavskyi#WA 1ms3944kbC++204.8kb2024-06-22 21:28:002024-06-22 21:28:01

Judging History

你现在查看的是最新测评结果

  • [2024-06-22 21:28:01]
  • 评测
  • 测评结果:WA
  • 用时:1ms
  • 内存:3944kb
  • [2024-06-22 21:28:00]
  • 提交

answer

#include <bits/stdc++.h>

using namespace std;

#define FOR(i, a, b) for(int i = (a); i < (b); i++)
#define RFOR(i, a, b) for(int i = (a) - 1; i >= (b); i--)
#define SZ(a) int(a.size())
#define ALL(a) a.begin(), a.end()
#define PB push_back
#define MP make_pair
#define F first
#define S second

typedef long long LL;
typedef vector<int> VI;
typedef pair<int, int> PII;
typedef double db;

const db EPS = 1e-9;
const db INF = 1e9;

template<typename T>
void updMin(T& a, T b)
{
	a = min(a, b);
}

struct Pt
{
	db x, y;
	Pt operator+(const Pt& p) const
	{
		return {x + p.x, y + p.y};
	}
	Pt operator-(const Pt& p) const
	{
		return {x - p.x, y - p.y};
	}
	Pt operator*(db d) const
	{
		return {x * d, y * d};
	}
	Pt operator/(db d) const
	{
		return {x / d, y / d};
	}
};

db sq(const Pt& p)
{
	return p.x * p.x + p.y * p.y;
}

db abs(const Pt& p)
{
	return sqrt(sq(p));
}

int sgn(db x)
{
	return (EPS < x) - (x < -EPS);
}

Pt perp(const Pt& p)
{
	return {-p.y, p.x};
}

db dot(const Pt& p, const Pt& q)
{
	return p.x * q.x + p.y * q.y;
}

db cross(const Pt& p, const Pt& q)
{
	return p.x * q.y - p.y * q.x;
}

db orient(const Pt& p, const Pt& q, const Pt& r)
{
	return cross(q - p, r - p) / abs(q - p);
}

ostream& operator<<(ostream& os, const Pt& p)
{
	return os << "(" << p.x << "," << p.y << ")";
}

struct Line
{
	Pt n;
	db c;
	Line(const Pt& p, const Pt& q):
		n(perp(q - p)), c(-dot(n, p)) {}
	db side(const Pt& p) const
	{
		return dot(n, p) + c;
	}
	db sqDist(const Pt& p) const
	{
		return side(p) * side(p) / (db)sq(n);
	}
	Pt proj(const Pt& p) const
	{
		return p - n * side(p) / sq(n);
	}
};

bool inDisk(const Pt& a, const Pt& b, const Pt& p)
{
	return sgn(dot(a - p, b - p)) <= 0;
}

bool onSegment(const Pt& a, const Pt& b, const Pt& p)
{
	return sgn(orient(a, b, p)) == 0 && inDisk(a, b, p);
}

bool properInter(const Pt& a, const Pt& b, const Pt& c, const Pt& d)
{
	db oa = orient(c, d, a);
	db ob = orient(c, d, b);
	db oc = orient(a, b, c);
	db od = orient(a, b, d);
	return sgn(oa) * sgn(ob) == -1 && sgn(oc) * sgn(od) == -1;
}

vector<Pt> circleLine(const Pt& o, db r, const Line& l)
{
	db h2 = r * r - l.sqDist(o);
	if (sgn(h2) == -1)
		return {};
	Pt p = l.proj(o);
	if (sgn(h2) == 0)
		return {p};
	Pt h = perp(l.n) * sqrt(h2) / abs(l.n);
	return {p - h, p + h};
}

int main()
{
	ios::sync_with_stdio(0);
	cin.tie(0);
	cout << fixed << setprecision(10);
	int n, m, r;
	cin >> n >> m >> r;
	vector<Pt> vertices;
	FOR(i, 0, n)
	{
		db x1, y1, x2, y2;
		cin >> x1 >> y1 >> x2 >> y2;
		vertices.PB({x1, y1});
		vertices.PB({x2, y1});
		vertices.PB({x2, y2});
		vertices.PB({x1, y2});
	}
	FOR(i, 0, m)
	{
		db x, y;
		cin >> x >> y;
		vertices.PB({x, y});
	}
	db xs, ys, xt, yt;
	cin >> xs >> ys >> xt >> yt;
	vertices.PB({xs, ys});
	vertices.PB({xt, yt});
	int k = SZ(vertices);
	vector dist(k, vector<db>(k, INF));
	auto check = [&](const Pt& p1, const Pt& p2) -> bool
	{
		bool ok = true;
		FOR(l, 0, n)
		{
			FOR(p, 0, 4)
			{
				Pt q1 = vertices[4 * l + p], q2 = vertices[4 * l + (p + 1) % 4];
				ok &= !properInter(p1, p2, q1, q2);
			}
			ok &= !(onSegment(p1, p2, vertices[4 * l]) && onSegment(p1, p2, vertices[4 * l + 2]));
			ok &= !(onSegment(p1, p2, vertices[4 * l + 1]) && onSegment(p1, p2, vertices[4 * l + 3]));
		}
		return ok;
	};
	auto checkPoint = [&](const Pt& pt) -> bool
	{
		FOR(l, 0, n)
		{
			bool inside = true;
			FOR(p, 0, 4)
			{
				Pt q1 = vertices[4 * l + p], q2 = vertices[4 * l + (p + 1) % 4];
				inside &= sgn(orient(q1, q2, pt)) >= 0;
			}
			if (inside)
				return false;
		}
		return true;
	};
	FOR(i, 0, k)
	{
		FOR(j, 0, k)
		{
			if (i == j)
			{
				dist[i][j] = 0;
				continue;
			}
			Pt p1 = vertices[i], p2 = vertices[j];
			bool blast = 4 * n <= i && i < 4 * n + m;
			if (check(p1, p2))
			{
				db d = abs(p2 - p1);
				if (blast)
					d = max(0.0, d - r);
				updMin(dist[i][j], d);
			}
			if (blast)
			{
				FOR(l, 0, n)
				{
					FOR(p, 0, 4)
					{
						Pt q1 = vertices[4 * l + p], q2 = vertices[4 * l + (p + 1) % 4];
						Line q12(q1, q2);
						vector<Pt> vec = circleLine(p1, r, q12);
						for (const Pt& pt : vec)
						{
							if (onSegment(q1, q2, pt) && check(pt, p2))
							{
								updMin(dist[i][j], abs(p2 - pt));
							}
						}
					}
				}
				if (r < abs(p2 - p1) - EPS)
				{
					Pt pt = p1 + (p2 - p1) / abs(p2 - p1) * r;
					if (check(pt, p2) && checkPoint(pt))
					{
						updMin(dist[i][j], abs(p2 - pt));
					}
				}
				else
				{
					dist[i][j] = 0;
				}
			}
		}
	}
	FOR(kk, 0, k)
		FOR(i, 0, k)
			FOR(j, 0, k)
				updMin(dist[i][j], dist[i][kk] + dist[kk][j]);
	cout << dist[k - 2][k - 1] << "\n";
	return 0;
}

详细

Test #1:

score: 100
Accepted
time: 0ms
memory: 3868kb

input:

1 2 2
0 2 7 4
-3 3
8 2
1 1 6 6

output:

9.5432037669

result:

ok found '9.5432038', expected '9.5432038', error '0.0000000'

Test #2:

score: 0
Accepted
time: 0ms
memory: 3944kb

input:

1 2 3
0 2 7 4
-1 4
8 2
1 1 6 6

output:

7.9303914292

result:

ok found '7.9303914', expected '7.9303914', error '0.0000000'

Test #3:

score: 0
Accepted
time: 0ms
memory: 3868kb

input:

1 2 2
2 2 7 4
-1 4
8 2
1 1 6 6

output:

7.6344136152

result:

ok found '7.6344136', expected '7.6344136', error '0.0000000'

Test #4:

score: 0
Accepted
time: 0ms
memory: 3792kb

input:

1 2 1
0 2 7 4
-4 4
8 2
1 1 6 6

output:

9.7387688827

result:

ok found '9.7387689', expected '9.7387689', error '0.0000000'

Test #5:

score: 0
Accepted
time: 0ms
memory: 3804kb

input:

1 2 2
0 2 7 5
-4 4
8 2
1 1 6 6

output:

9.6475590344

result:

ok found '9.6475590', expected '9.6475590', error '0.0000000'

Test #6:

score: 0
Accepted
time: 0ms
memory: 3796kb

input:

1 0 114514
0 0 6 2
2 -1 5 3

output:

7.5373191880

result:

ok found '7.5373192', expected '7.5373192', error '0.0000000'

Test #7:

score: 0
Accepted
time: 0ms
memory: 3880kb

input:

5 4 10
1 -99999 9 99999
11 -99999 19 99999
21 -99999 23 99999
-99999 999999 99999 1000000
-99999 -1000000 99999 -999999
0 0
10 0
20 0
24 7
-1 0 30 7

output:

1.0000000000

result:

ok found '1.0000000', expected '1.0000000', error '0.0000000'

Test #8:

score: 0
Accepted
time: 1ms
memory: 3884kb

input:

5 3 10
1 -99999 9 99999
11 -99999 19 99999
21 -99999 23 99999
-99999 999999 99999 1000000
-99999 -1000000 99999 -999999
0 0
10 0
20 0
-1 0 30 7

output:

3.2065556157

result:

ok found '3.2065556', expected '3.2065556', error '0.0000000'

Test #9:

score: -100
Wrong Answer
time: 1ms
memory: 3812kb

input:

5 4 1
1 -99999 9 99999
11 -99999 19 99999
21 -99999 23 99999
-99999 999999 99999 1000000
-99999 -1000000 99999 -999999
0 0
10 0
20 0
24 7
-1 0 30 7

output:

200006.0005650228

result:

wrong answer 1st numbers differ - expected: '200013.0002500', found: '200006.0005650', error = '0.0000350'