QOJ.ac

QOJ

IDProblemSubmitterResultTimeMemoryLanguageFile sizeSubmit timeJudge time
#54606#972. CircleYaoBIG#AC ✓610ms4440kbC++4.4kb2022-10-09 20:22:242022-10-09 20:22:24

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 20:22:24]
  • 评测
  • 测评结果:AC
  • 用时:610ms
  • 内存:4440kb
  • [2022-10-09 20:22:24]
  • 提交

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 dot(P b) const { return x * b.x + y * b.y; }
	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 project_len(P a, P b) const {
		if (isInt) return (*this - a).dot(b - a);
		else if (a == b) return 0;
		else return (*this - a).dot(b - a) / (b - a).len();
	}

	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();
	}
	
	T dis_to_seg(P a, P b) const {
		if (project_len(a, b) <= eps) return (*this - a).len();
		if (project_len(b, a) <= eps) return (*this - b).len();
		return fabs(dis_to_line(a, b));
	}

	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;
		// debug(P{}.dis_to_seg(a, b), r);
		if (P::cmp(P{}.dis_to_seg(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;
			}
			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: 3ms
memory: 4388kb

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: 0
Accepted
time: 585ms
memory: 4440kb

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
11.180
5.102
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
17.102
17.045
21.845
20.463
11.735
5.657
17.511
28.328
11.520
10.298
14.765
26.516
23.500
23.901
29.973
23.523
15.324
31.3...

result:

ok 100000 tokens

Test #3:

score: 0
Accepted
time: 556ms
memory: 4312kb

input:

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

output:

14.571
20.073
14.699
13.091
13.483
40.275
7.763
7.430
17.920
5.831
15.386
9.144
16.861
21.974
29.270
15.667
21.024
14.336
19.970
20.850
35.180
15.158
5.000
8.844
13.799
27.803
17.549
15.395
30.598
15.420
18.148
11.447
16.646
22.192
9.062
18.266
22.636
12.331
18.850
13.002
17.786
9.280
14.138
18.164
...

result:

ok 100000 tokens

Test #4:

score: 0
Accepted
time: 575ms
memory: 4412kb

input:

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

output:

15.145
15.704
20.283
16.832
33.337
17.299
20.109
20.366
10.468
16.358
17.241
23.132
19.226
13.117
14.891
31.987
22.165
17.290
15.675
36.938
19.550
15.103
21.134
12.175
25.859
18.339
14.831
13.684
12.791
13.091
5.657
16.585
19.661
27.292
26.161
13.570
9.697
16.106
17.800
21.011
21.113
8.490
24.768
30...

result:

ok 100000 tokens

Test #5:

score: 0
Accepted
time: 598ms
memory: 4332kb

input:

100000
-888 252 735 -600 354 917 115
823 -392 -224 23 -927 133 559
-480 648 545 -735 -221 780 1
-929 933 -27 457 165 435 169
96 215 -788 757 -995 -218 667
-315 -925 582 -980 329 -162 315
495 322 -979 673 -467 -781 589
-261 161 718 330 -890 -766 778
599 -261 -618 -181 -79 -198 429
-892 729 -949 672 5...

output:

2795.207
1426.301
1986.922
1065.587
1179.904
1336.880
2074.228
1569.596
1516.343
2047.076
2037.565
1278.256
1366.915
704.215
1637.810
823.846
1687.226
1411.903
1985.605
2226.704
2408.212
419.518
3168.560
1582.364
734.685
1266.701
2931.680
1921.424
567.081
1639.716
2808.834
2541.282
1182.642
2148.445...

result:

ok 100000 tokens

Test #6:

score: 0
Accepted
time: 610ms
memory: 4220kb

input:

100000
311 -823 238 -177 14 942 414
458 -867 611 877 -596 500 434
-102 -509 873 -974 424 -322 537
-331 -543 676 -247 815 646 687
-53 -52 -381 -433 999 -569 715
66 51 -888 579 650 475 301
670 568 -432 34 -571 550 395
0 -423 466 -396 -932 412 35
-98 665 791 -320 670 755 710
200 -926 -644 211 920 -434 ...

output:

2103.154
2333.474
1126.332
1326.118
1180.103
1712.197
1280.231
2796.425
1338.385
1733.371
1397.161
2224.141
2997.568
2301.324
2463.509
2143.719
1424.038
1232.972
2319.448
571.006
2821.620
1578.404
1296.411
1517.902
728.982
2163.288
2420.932
1793.361
1321.645
2143.605
3151.535
1031.383
1820.310
1638....

result:

ok 100000 tokens