QOJ.ac

QOJ

IDProblemSubmitterResultTimeMemoryLanguageFile sizeSubmit timeJudge time
#54596#972. CircleYaoBIG#WA 491ms4432kbC++4.0kb2022-10-09 19:58:492022-10-09 19:58:52

Judging History

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

  • [2023-08-10 23:21:45]
  • System Update: QOJ starts to keep a history of the judgings of all the submissions.
  • [2022-10-09 19:58:52]
  • 评测
  • 测评结果:WA
  • 用时:491ms
  • 内存:4432kb
  • [2022-10-09 19:58:49]
  • 提交

answer

#include "bits/stdc++.h"
#define rep(i, a, n) for (auto i = a; i <= (n); ++i)
#define revrep(i, a, n) for (auto i = n; i >= (a); --i)
#define all(a) a.begin(), a.end()
#define sz(a) (int)(a).size()
template<class T> bool chmin(T &a, T b) { if (b < a) { a = b; return 1; } else return 0; }
template<class T> bool chmax(T &a, T b) { if (b > a) { a = b; return 1; } else return 0; }
using namespace std;

template<class A> string to_string(const A &v) {
	bool first = 1;
	string res = "{";
	for (const auto &x: v) {
		if (!first) res += ", ";
		first = 0;
		res += to_string(x);
	}
	res += ")";
	return res;
}

void debug_out() { cerr << endl; }
template<class H, class... T> void debug_out(const H&h, const T&... t) {
	cerr << " " << to_string(h);
	debug_out(t...);
}
#define debug(...) cerr << "[" << #__VA_ARGS__ << "]:", debug_out(__VA_ARGS__)

using ll = long long;
using pii = pair<int, int>;
using vi = vector<int>;
using vvi = vector<int>;

template<class T> struct Point {
	using P = Point;
	using type = T;
	static constexpr T eps = 1e-9;
	static constexpr bool isInt = is_integral_v<T>;
	
	static int sgn(T x) { return (x > eps) - (x < -eps); }
	static int cmp(T x, T y) { return sgn(x - y); }

	T x, y;

	P operator +(P a) const { return P{x + a.x, y + a.y}; }
	P operator -(P a) const { return P{x - a.x, y - a.y}; }
	P operator *(T a) const { return P{x * a, y * a}; }
	P operator /(T a) const { return P{x / a, y / a}; }
	bool operator ==(P a) { return cmp(x, a.x) == 0 && cmp(y, a.y) == 0; }

	T len2() const { return x * x + y * y; }
	T len() const { return sqrt(x * x + y * y); }

	P unit() const { 
		if (isInt) return *this;
		else return len() <= eps ? P{} : *this / len();
	}

	T cross(P b) const { return x * b.y - y * b.x; }

	P rotate(T theta) const {
		P a{cos(theta), sin(theta)};
		return P{x * a.x - y * a.y, x * a.y + y * a.x};
	}

	T dis_to_line(P a, P b) const {
		if (isInt) return (*this - a).cross(b - a);
		else if (a == b) return 0;
		else return (*this - a).cross(b - a) / (b - a).len();
	}

	friend string to_string(P p) { return "(" + to_string(p.x) + ", " + to_string(p.y) + ")"; }
};

template<class T, class P = Point<T>>
vector<P> PointCircleTagentPoints(P a, P o, T r) {
	P u = o - a;
	if (P::cmp(u.len2(), r * r) <= 0) return {};
	T d = sqrt(max(u.len2() - r * r, T{0}));
	T theta = asin(min(r / u.len(), T{1}));
	P v = u.unit();
	return {a + v.rotate(-theta) * d, a + v.rotate(theta) * d};
}

int main() {
	ios::sync_with_stdio(0); cin.tie(0);

	using T = double;
	using P = Point<T>;

	int cas; cin >> cas; while (cas--) {
		P a, b, c; T r;
		cin >> a.x >> a.y;
		cin >> b.x >> b.y;
		cin >> c.x >> c.y;
		cin >> r;
		a = a - c;
		b = b - c;
		if (a == b) puts("0.000");
		else if (P::cmp(abs(P{}.dis_to_line(a, b)), r) <= 0) {
			T ans = 1e100;
			vector<P> as = a.len2() == r * r ? vector<P>{a} : PointCircleTagentPoints(a, P{}, r);
			vector<P> bs = b.len2() == r * r ? vector<P>{b} : PointCircleTagentPoints(b, P{}, r);
			for (auto p: as) for (auto q: bs) {
				T t1 = atan2(p.y, p.x);
				T t2 = atan2(q.y, q.x);
				T t = t1 - t2;
				const T pi = acos(-1.0);
				while (t > pi) t -= pi * 2;
				while (t <= -pi) t += pi * 2;
				chmin(ans, (a - p).len() +  (b - q).len() + r * abs(t));
			}
			printf("%.3f\n", ans);
		} else {
			T t1 = atan2(a.y, a.x);
			T t2 = atan2(b.y, b.x);
			T t = t1 - t2;
			const T pi = acos(-1.0);
			while (t > pi) t -= pi * 2;
			while (t <= -pi) t += pi * 2;
			if (t < 0) {
				swap(a, b);
				t = -t;
			}
			// debug(a, b, t);
			T lo = 0, hi = t;
			T la = a.len();
			T lb = b.len();
			rep(_, 1, 40) {
				auto get = [&](T d, T theta) {
					T y = d * sin(theta);
					T x = d * cos(theta) - r;
					return atan2(y, x);
				};
				T mid = (lo + hi) / 2;
				if (get(la, mid) - get(lb, t - mid) > 0) hi = mid;
				else lo = mid;
			}
			P u = a.unit().rotate(-(lo + hi) / 2) * r;
			// debug(u);
			T ans = (a - u).len() + (b - u).len();
			printf("%.3f\n", ans);
		}
	}
	return 0;
}

Details

Tip: Click on the bar to expand more detailed information

Test #1:

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

input:

3
0 0 2 2 1 1 1
0 0 2 2 1 0 1
0 0 2 2 1 -1 1

output:

3.571
2.927
3.116

result:

ok 3 tokens

Test #2:

score: -100
Wrong Answer
time: 491ms
memory: 4372kb

input:

100000
-9 -2 10 -3 -5 1 1
-7 0 -5 5 4 -8 10
6 -7 -2 -4 0 10 1
-5 -4 9 3 2 -10 9
10 3 1 -10 -10 -5 7
0 4 4 -1 2 6 2
-8 -10 4 -2 -1 4 3
2 8 4 10 -4 -9 4
8 0 -4 -10 8 -2 1
8 -4 -2 9 2 -3 3
-10 6 -4 1 6 2 8
-6 -7 -10 -4 1 -6 7
4 9 -1 9 -1 4 5
0 -7 4 1 10 -3 7
5 4 1 6 8 -6 1
7 8 -3 -9 -7 -1 5
-5 -2 -8 9 ...

output:

19.764
10.267
30.231
15.704
21.568
7.086
18.779
30.648
15.732
16.598
21.062
12.732
5.000
8.957
22.348
20.509
11.755
12.130
25.936
18.512
26.847
17.582
22.441
19.312
27.234
23.249
20.793
25.681
25.548
20.463
11.735
5.657
25.533
28.328
11.520
10.298
14.765
26.516
23.500
23.901
29.973
23.523
15.324
31....

result:

wrong answer 11th words differ - expected: '11.180', found: '21.062'