QOJ.ac

QOJ

IDProblemSubmitterResultTimeMemoryLanguageFile sizeSubmit timeJudge time
#109322#6517. Computational GeometryxuxubaobaoWA 3ms3556kbC++172.5kb2023-05-28 14:01:122023-05-28 14:01:14

Judging History

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

  • [2023-08-10 23:21:45]
  • System Update: QOJ starts to keep a history of the judgings of all the submissions.
  • [2023-05-28 14:01:14]
  • 评测
  • 测评结果:WA
  • 用时:3ms
  • 内存:3556kb
  • [2023-05-28 14:01:12]
  • 提交

answer

// Super Idol的笑容
//    都没你的甜
//  八月正午的阳光
//    都没你耀眼
//  热爱105°C的你
// 滴滴清纯的蒸馏水

#include <bits/stdc++.h>

#define double long double
#define int long long
using namespace std;
using PII = pair<int,int>;
using ll = long long;

int n;

struct point{long long x,y;}pk[5010 * 2], s[5010 * 2],tmp;
int inf = 1ll << 62;
int tot;

long long f(point c1,point a,point c2,point b){//叉积
	return (a.x-c1.x)*(b.y-c2.y)-(b.x-c2.x)*(a.y-c1.y);
}

long long sqr(long long x){  return x*x;}

long long dis(point m,point n){
	return sqr(abs(m.x-n.x))+sqr(abs(m.y-n.y));
}

bool cmp(point p,point q){//其他大佬好像都是用atan2直接求的极角大小,我用的叉积。
	long long t=f(pk[0],p,pk[0],q);
	if(t>0)//如果叉积为正,则说明转的方向是对的
		return 1;
	if(!t)//如果出现三点共线的情况就比较距离
		return dis(pk[0],p)<dis(pk[0],q);
	return 0;
}


double mianji(point a,point b,point c){//求三点组成的三角形的面积 蒟蒻只会用割补法
	double xi=min(a.x,min(b.x,c.x));
	double yi=min(a.y,min(b.y,c.y));
	double xa=max(a.x,max(b.x,c.x));
	double ya=max(a.y,max(b.y,c.y));
	double ansi=(xa-xi)*(ya-yi);
	ansi-=(max(a.x,b.x)-min(a.x,b.x))*(max(a.y,b.y)-min(a.y,b.y))/2;
	ansi-=(max(a.x,c.x)-min(a.x,c.x))*(max(a.y,c.y)-min(a.y,c.y))/2;
	ansi-=(max(c.x,b.x)-min(c.x,b.x))*(max(c.y,b.y)-min(c.y,b.y))/2;
	return ansi / 2;
}

ll dp[5010 * 2][5010 * 2];
ll dist[5010 * 2][5010 * 2];

void solve() {
	tot = 0;
	cin >> n;
	for(int i = 0; i < n; i ++) cin >> s[i].x >> s[i].y;
	for(int i = n; i < 2 * n; i ++) s[i] = s[i - n];
	for(int i = 0; i < 2 * n; i ++) {
		for(int j = i + 1; j < 2 * n; j ++) {
			dist[i][j] = max(dist[i][j - 1], dis(s[i], s[j]));
		}
	}
	for(int len = 2; len <= n; len ++) {
		for(int l = 0; l + len - 1 < 2 * n; l ++) {
			int r = l + len - 1;
			dp[l][r] = max(dp[l + 1][r], dist[l][r]);
		}
	}
	double ans = 0;
	for(int i = 2; i < n; i ++){
		ans += mianji(s[0], s[i - 1], s[i]);
	}
	ll maxs = 1ll << 62;
	for(int i = 0; i < n; i ++) {
		double sum = 0;
		for(int j = i + 2; j <= i + n - 2; j ++) {
			sum += mianji(s[i], s[j - 1], s[j]);
			double g1 = sum;
			double g2 = ans - sum;
			if(g1 && g2) {
				maxs = min({dp[i][j] + dp[j][i + n], maxs});
			}
		}
	}
	cout << maxs << "\n";
}

signed main(){
	ios::sync_with_stdio(0);
	cin.tie(0);
	cout.tie(0);
	int t = 1;
	cin >> t;
	while(t--) {
		solve();
	}
}

Details

Tip: Click on the bar to expand more detailed information

Test #1:

score: 100
Accepted
time: 2ms
memory: 3468kb

input:

2
4
1 0
2 0
1 1
0 0
6
10 4
9 7
5 7
4 5
6 4
9 3

output:

4
44

result:

ok 2 number(s): "4 44"

Test #2:

score: -100
Wrong Answer
time: 3ms
memory: 3556kb

input:

713
8
8 25
3 15
0 5
10 0
19 2
24 6
23 15
15 34
8
25 16
18 25
10 32
1 23
0 14
21 0
27 2
32 6
7
16 15
8 20
1 16
0 12
16 0
21 1
24 5
7
15 1
18 0
24 8
27 15
4 19
0 17
7 8
4
10 20
0 30
15 0
14 10
6
15 0
24 10
21 14
12 14
7 11
0 3
7
18 7
16 9
12 10
6 9
0 4
5 0
15 1
9
0 23
8 13
14 6
24 0
34 1
41 11
37 20
1...

output:

1075
1389
706
687
1550
497
300
1668
471
162
519
190
786
983
367
930
580
524
509
275
617
298
146
1330
494
965
599
1321
866
1210
233
398
560
1548
871
938
366
500
371
1118
1222
1994
712
586
858
624
697
575
1274
882
1035
406
934
670
990
1231
513
2871
939
2735
1610
834
721
585
203
198
1666
617
1166
326
2...

result:

wrong answer 120th numbers differ - expected: '294', found: '284'