QOJ.ac

QOJ

IDProblemSubmitterResultTimeMemoryLanguageFile sizeSubmit timeJudge time
#202533#6542. Optimal Quadratic Functionucup-team1209WA 39ms13448kbC++203.5kb2023-10-06 11:07:092023-10-06 11:07:09

Judging History

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

  • [2023-10-06 11:07:09]
  • 评测
  • 测评结果:WA
  • 用时:39ms
  • 内存:13448kb
  • [2023-10-06 11:07:09]
  • 提交

answer

#include<bits/stdc++.h>
using std::cin;
using std::cout;
using ll = long long;
using u64 = unsigned long long;
void IOinit() {
	std::ios::sync_with_stdio(false), cin.tie(0);
#ifdef zqj
	freopen("$.in", "r", stdin);
#endif
}
using db = long double;
int T, n;
const int N = 100000;
const db eps = 1e-9;
db sgn(db x) { return x < -eps ? -1 : x > eps; }
db eq(db x, db y) { return !sgn(x - y); }
struct vec2 {
	db x, y;
	db norm() const { return x * x + y * y; }
	db abs() const { return std::sqrt(x * x + y * y); }
	db arg() const { return atan2(y, x); }
};
vec2 r90(vec2 x) { return {-x.y, x.x}; }
vec2 operator + (vec2 x, vec2 y) { return {x.x + y.x, x.y + y.y}; }
vec2 operator - (vec2 x, vec2 y) { return {x.x - y.x, x.y - y.y}; }
vec2 operator / (vec2 x, db y) { return {x.x / y, x.y / y}; }
vec2 operator * (vec2 x, db y) { return {x.x * y, x.y * y}; }
vec2 operator * (db y, vec2 x) { return {x.x * y, x.y * y}; }
db operator * (vec2 x, vec2 y) { return x.x * y.y - x.y * y.x; }
db operator % (vec2 x, vec2 y) { return x.x * y.x + x.y * y.y; }

struct line : vec2 {
	db z;
	// a * x + b * y + c (= or >) 0
	line() = default;
	line(db a, db b, db c) : vec2{a, b}, z(c) {}
	line(vec2 a, vec2 b) : vec2(r90(b - a)), z(a * b) { }
	// 左侧 > 0
	db operator ()(vec2 a) const { return a % vec2(*this) + z; }
	line perp() const { return {y, -x, 0}; } // 垂直
	line para(vec2 o) { return {x, y, z - (*this)(o)}; } // 平行
};
vec2 operator & (line x, line y) {
	return vec2{vec2{x.z, x.y} * vec2{y.z, y.y}, vec2{x.x, x.z} * vec2{y.x, y.z}} / -(vec2(x) * vec2(y));
	// 注意此处精度误差较大,以及 res.y 需要较高精度
}

std::vector<vec2> cut(const std::vector<vec2> & o, line l) {
	std::vector<vec2> res;
	int n = size(o);
	for(int i = 0;i < n;++i) {
		vec2 a = o[i], b = o[(i + 1) % n];
		if(sgn(l(a)) >= 0) res.push_back(a); // 注意 sgn 精度
		if(sgn(l(a)) * sgn(l(b)) < 0) res.push_back(line(a, b) & l);
	}
	return res;
} // 切凸包
db x[N], y[N], o[N];
db eval(db a, db b) {
	db min = y[0] - a * x[0] * x[0] - b * x[0];
	db max = min;
	for(int i = 1;i < n;++i) {
		db v = y[i] - a * x[i] * x[i] - b * x[i];
		if(max < v) max = v;
		if(min > v) min = v;
	}
	return max - min;
}
vec2 eval_d(db a, db b) {
	db min = y[0] - a * x[0] * x[0] - b * x[0], damin = -x[0] * x[0], dbmin = -x[0];
	db max = min, damax = -x[0] * x[0], dbmax = -x[0];
	for(int i = 1;i < n;++i) {
		db v = y[i] - a * x[i] * x[i] - b * x[i];
		if(max < v) max = v, damax = -x[i] * x[i], dbmax = -x[i];
		if(min > v) min = v, damin = -x[i] * x[i], dbmin = -x[i];
	}
	return {damax - damin, dbmax - dbmin};
}


int main() {
	IOinit();
	cin >> T;
	for(int i = 0;i < T;++i) {
		cin >> n;
		for(int i = 0;i < n;++i) {
			cin >> x[i] >> y[i];
		}
		const db V = 1e12;
		std::vector<vec2> v = { {-V, -V}, {V, - V}, {V, V}, {-V, V} };
		auto center = [&]() -> vec2 {
			vec2 sum = v[0];
			for(int j = 1;j < (int) v.size();++j) sum = sum + v[j];
			sum = sum / v.size();
			return sum;
		};
		for(int i = 0;i < 200;++i) {
			vec2 x = center(), d = eval_d(x.x, x.y);
			d.x *= -1, d.y *= -1;
			line L; L.x = d.x, L.y = d.y; L = L.para(x);
			v = cut(v, L);
			assert(v.size());
		}
		//for(auto [x, y] : v) {
		////	std::cerr << "de " << x << ' ' << y << '\n';
		//}
		auto c = center();
		//std::cerr << c.x << '\n';
		//std::cerr << c.y << '\n';
		db res = eval(c.x, c.y) / 2;
		printf("%.10Lf\n", res * res);
		// cout << res * res << '\n';
	}
}

Details

Tip: Click on the bar to expand more detailed information

Test #1:

score: 100
Accepted
time: 1ms
memory: 6008kb

input:

1
4
0 0
1 3
2 9
3 0

output:

5.0625000002

result:

ok found '5.0625000', expected '5.0625000', error '0.0000000'

Test #2:

score: -100
Wrong Answer
time: 39ms
memory: 13448kb

input:

60
1
1000 -990
2
171 -638
949 -99
2
633 227
-257 -602
3
634 -994
633 999
-374 995
3
445 -110
586 -121
462 29
9
-995 -224
-458 -833
691 -670
456 -259
-376 55
-563 -12
834 827
-826 -220
299 744
17
997 991
997 976
997 988
998 -986
999 -982
999 -980
999 -996
998 -988
998 -991
997 987
1000 996
999 -1000
...

output:

0.0000000000
0.0000027726
0.0000070492
0.0000000000
0.0000000000
543160.1259984399
121.0000000000
0.8320062103
412780.6071837651
12.2500000000
15750.2500010519
118751.3800864252
880245.5054746125
1.0000090869
15.3633733719
854986.7131655892
20.2500000000
24567.6673811331
881031.5630215130
306.250008...

result:

wrong answer 2nd numbers differ - expected: '0.0000000', found: '0.0000028', error = '0.0000028'