QOJ.ac

QOJ

IDProblemSubmitterResultTimeMemoryLanguageFile sizeSubmit timeJudge time
#188673#4886. Best SunDualqwqWA 47ms4232kbC++234.9kb2023-09-26 11:04:372023-09-26 11:04:38

Judging History

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

  • [2023-09-26 11:04:38]
  • 评测
  • 测评结果:WA
  • 用时:47ms
  • 内存:4232kb
  • [2023-09-26 11:04:37]
  • 提交

answer

#include <bits/stdc++.h>
using namespace std;
const int N = 3e2 + 5;
typedef long long i64;
typedef double db;
typedef pair<int,int> pii;
#define FI first
#define SE second
const db eps = 1e-9,PI = acos(-1.0);
mt19937 Rnd(114514);
struct Vec {
	int x,y;
	Vec(){}
	Vec(const int _x,const int _y):x(_x),y(_y){}
	Vec operator + (const Vec &rhs) const { return Vec(x + rhs.x,y + rhs.y);}
	Vec operator - (const Vec &rhs) const { return Vec(x - rhs.x,y - rhs.y);}
	i64 operator * (const Vec &rhs) const { return 1ll * x * rhs.y - 1ll * y * rhs.x;}
};
Vec O(0,0);
bool Cmp(const Vec &x,const Vec &y) { return (x.x != y.x) ? (x.x < y.x) : (x.y < y.y);}
i64 Dot(const Vec &A,const Vec &B) { return 1ll * A.x * B.x + 1ll * A.y * B.y;}
db Distance(const Vec &A,const Vec &B) { return sqrt(Dot(A - B,A - B));}
db Angle(const Vec &A) { 
	db tmp = atan2(A.y,A.x);
	if(tmp < -eps) return tmp + PI * 2;
	else return tmp;
}
db Area(const Vec &A,const Vec &B,const Vec &C) { return 0.5 * fabs(A * B + B * C + C * A);}
bool Equal(const db &A,const db &B) { return fabs(A - B) < eps;}
db Angle(const Vec &A,const Vec &B,const Vec &C) { // jiao ABC
	return Angle(A - B) - Angle(C - B);
}
bool InSegment(const Vec &A,const Vec &B,const Vec &p) { return Equal(Distance(A,p) + Distance(p,B),Distance(A,B));}
bool InTriangle(const Vec &A,const Vec &B,const Vec &C,const Vec &p) {
	return Equal(Area(A,B,p) + Area(B,C,p) + Area(C,A,p),Area(A,B,C));
}
Vec Rotate(const Vec &A) { return Vec(-A.y,A.x);}
Vec p[N];
int n;
int V[N][N],VL[N][N]; 
db sum[N][N];
inline bool CheckTriangle(int i,int j,int k) {
	// for(int t = 1;t <= n;t++)
	// 	if(i != t && j != t && k != t && InTriangle(p[i],p[j],p[k],p[t])) return 0;
	// return 1;
	if(VL[i][j] || VL[j][k] || VL[i][k]) return false;
	if(i == k || j == k || j == i) return true;
	// if(i == 1 && j == 1 && k == 4) puts("done");
	int num = 0;
	if(p[i] * p[j] > 0) num += V[i][j]; else num -= V[i][j];
	if(p[j] * p[k] > 0) num += V[j][k]; else num -= V[j][k];
	if(p[k] * p[i] > 0) num += V[k][i]; else num -= V[k][i];
	return num == 0;
}

struct Line {
	int s,t,type;
	Vec v;
	Line(){}
	Line(const int _s,const int _t,const int _type,const Vec _v):
		s(_s),t(_t),type(_type),v(_v){}
	bool operator < (const Line &rhs) const { return Angle(v) < Angle(rhs.v);}
};
Line L[N * N];
int tot;
inline void Init() {
	cin >> n;
	for(int i = 1;i <= n;i++) cin >> p[i].x >> p[i].y;
	sort(p + 1,p + n + 1,Cmp);
	for(int i = 1;i <= n;i++) 
		for(int j = 1;j <= n;j++)
			for(int k = 1;k <= n;k++) {
				if(k == i || k == j) continue;	
				if(!InTriangle(p[i],O,p[j],p[k])) continue;
				if(InSegment(p[i],p[j],p[k]) || (!InSegment(O,p[i],p[k]) && !InSegment(O,p[j],p[k])))
					++V[i][j];
				if(InSegment(p[i],p[j],p[k])) ++VL[i][j];
			}
	// printf("V,VL[1,4]:%d,%d\n",V[1][4],VL[1][4]);
	// printf("V,VL[1,1]:%d,%d\n",V[1][1],VL[1][1]);

	for(int i = 1;i <= n;i++)
		for(int j = 1;j <= n;j++)
			for(int k = 1;k <= n;k++) {
				if(k == i || k == j) continue;
				if((p[k] - p[i]) * (p[j] - p[i]) <= 0) continue;
				if(fabs(Angle(p[k],p[i],p[j])) < PI / 2 && fabs(Angle(p[k],p[j],p[i])) < PI / 2)
					sum[i][j] += min(Distance(p[k],p[i]),Distance(p[k],p[j]));
			}
	for(int i = 1;i <= n;i++)
		for(int j = 1;j <= n;j++) {
			if(i == j) continue;
			sum[i][j] += Distance(p[i],p[j]);
			L[++tot] = Line(i,j,0,p[j] - p[i]);
			L[++tot] = Line(i,j,1,Rotate(p[j] - p[i]));
		}
	// printf("Angle(1,2):%.6lf\n",Angle(p[2] - p[1]));
	// printf("Angle(1,3):%.6lf\n",Angle(p[3] - p[1]));
	// printf("Angle(2,1):%.6lf\n",Angle(p[1] - p[2]));
	// printf("Angle(2,3):%.6lf\n",Angle(p[3] - p[2]));
	// printf("Angle(3,1):%.6lf\n",Angle(p[1] - p[3]));
	// printf("Angle(3,2):%.6lf\n",Angle(p[2] - p[3]));

	sort(L + 1,L + tot + 1);
}

db dp[N];
inline bool Check(int st,db mid) {
	for(int i = 1;i <= n;i++) dp[i] = -1e18;
	dp[st] = -eps;
	// printf("Check:%d\n",st);
	for(int i = 1;i <= tot;i++) {
		int s = L[i].s,t = L[i].t,tp = L[i].type;
		// printf("L:%d,%d,%d\n",s,t,tp);
		// printf("CheckTriangle[%d,%d,%d]:%d\n",st,s,t,CheckTriangle(st,s,t));
		if(tp == 1) {
			if(s >= st) dp[s] -= mid * Distance(p[s],p[t]);
		} else 
			if(s >= st && t >= st && CheckTriangle(st,s,t))
				dp[t] = max(dp[t],dp[s] + Area(p[st],p[s],p[t]) - mid * sum[s][t]); 
	}
	return dp[st] > eps;
}
inline void Clr(int n) {
	for(int i = 1;i <= n;i++) for(int j = 1;j <= n;j++) V[i][j] = VL[i][j] = sum[i][j] = 0;
	tot = 0;
}
inline void work() {
	Clr(n);
	Init();
	static int perm[N];
	for(int i = 1;i <= n;i++) perm[i] = i;
	shuffle(perm + 1,perm + n + 1,Rnd);
	db ans = 0;
	for(int i = 1;i <= n;i++) 
		if(Check(i,ans)) {
			db lef = ans,rig = 1e13;
			for(int _ = 1;_ <= 80;_++) {
				db mid = (lef + rig) / 2;
				if(Check(i,mid)) lef = mid;
				else rig = mid;
			}
			ans = lef;
		}
	printf("%.10lf\n",ans);
}
int main() {
	int T;
	cin >> T;
	while(T--) work();
	return 0;
}
/*
1
4
0 0
10 0
0 10
8 1
*/

Details

Tip: Click on the bar to expand more detailed information

Test #1:

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

input:

4
3
-1 -1
1 -1
0 1
4
0 0
10 0
0 10
8 1
5
2 0
-2 0
1 1
-1 1
0 3
8
4 4
-4 4
4 -4
-4 -4
5 6
-6 5
-5 -6
6 -5

output:

0.3090169941
1.2368614276
0.2711375413
1.5631002094

result:

ok 4 numbers

Test #2:

score: -100
Wrong Answer
time: 47ms
memory: 4220kb

input:

10000
3
702262 828158
-350821 -420883
-466450 13507
3
28647 -193498
126436 -864937
-287798 738936
3
270358 -269567
745815 -485408
834083 677952
3
-2036 -403634
742978 -263774
975937 -609237
3
584248 -472620
482016 -356760
284902 903881
3
-292004 504925
-935756 373793
-781101 -434659
3
-858513 684433...

output:

0.0000000000
0.0000000000
0.0000000000
0.0000000000
0.0000000000
0.0000000000
0.0000000000
0.0000000000
0.0000000000
0.0000000000
0.0000000000
0.0000000000
0.0000000000
0.0000000000
0.0000000000
99775.9271965681
0.0000000000
0.0000000000
0.0000000000
5236.4144265452
0.0000000000
137073.6440903351
0....

result:

wrong answer 1st numbers differ - expected: '85789.0873984', found: '0.0000000', error = '1.0000000'