QOJ.ac

QOJ

IDProblemSubmitterResultTimeMemoryLanguageFile sizeSubmit timeJudge time
#786568#9520. Concave HullSZH#WA 0ms9964kbC++144.4kb2024-11-26 22:04:162024-11-26 22:04:17

Judging History

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

  • [2024-11-26 22:04:17]
  • 评测
  • 测评结果:WA
  • 用时:0ms
  • 内存:9964kb
  • [2024-11-26 22:04:16]
  • 提交

answer

#include<bits/stdc++.h>
#define pa pair<int,int>
#define INF 0x3f3f3f3f
#define inf 0x3f
#define fi first
#define se second
#define mp make_pair
#define ll long long
#define ull unsigned long long
#define pb push_back

using namespace std;

inline ll read()
{
	ll f=1,sum=0;char c=getchar();
	while (!isdigit(c)) {if (c=='-') f=-1;c=getchar();}
	while (isdigit(c)) {sum=sum*10+c-'0';c=getchar();}
	return sum*f;
}

const double eps = 1e-10;
const int N = 2e5+5;

int sgn(double x){
	if(fabs(x)<eps) return 0;
	return x<0?-1:1;
}

int dcmp(double x, double y){
	return sgn(x-y);
}

struct Point{
	ll x,y;
	Point(){}
	Point(ll x,ll y):x(x),y(y){}
	Point operator + (Point B){return Point(x+B.x, y+B.y); }
	Point operator - (Point B){return Point(x-B.x, y-B.y); }
	Point operator * (double k){return Point(x*k, y*k); }
	Point operator + (double k){return Point(x/k, y/k); }
	bool operator ==(Point B){return sgn(x-B.x)==0 && sgn(y-B.y)==0;}
	bool operator <(Point B){
		return sgn(x-B.x)<0 || (sgn(x-B.x)==0 && sgn(y-B.y)<0);
	}

	void print(){
		printf("  x=%lld, y=%lld\n",x,y);
	}
	void scan(){
		// scanf("%lf%lf",&x,&y);
		x=read(); y=read();
	}
};
typedef Point Vector;

double Cross(Vector A, Vector B){
	return A.x*B.y-A.y*B.x;
}

double Distance(Point A, Point B){
	return sqrt((A.x-B.x)*(A.x-B.x) + (A.y-B.y)*(A.y-B.y));
}

struct Line{
	Point p1,p2;
	Line(){}
	Line(Point p1,Point p2):p1(p1),p2(p2){}
};

double Dis_point_line(Point p, Line v){
	return fabs(Cross(p-v.p1, v.p2-v.p1))/Distance(v.p1, v.p2);
}

vector<int> rec_ind;

int Convec_hull(Point *p, int n, Point *ch){
	n=unique(p,p+n)-p;
	sort(p,p+n);
	int v=0;
	for(int i=0;i<n;i++){
		while(v>1 && sgn(Cross(ch[v-1]-ch[v-2],p[i]-ch[v-1]))<=0){
			v--;
			rec_ind.pop_back();
		}
		ch[v++] = p[i];
		rec_ind.push_back(i);
	}
	int j=v;
	for(int i=n-2;i>=0;i--){
		while(v>j && sgn(Cross(ch[v-1]-ch[v-2],p[i]-ch[v-1]))<=0){
			v--;
			rec_ind.pop_back();
		}
		ch[v++] = p[i];
		rec_ind.push_back(i);
	}
	if(n>1){ 
		v--;
		rec_ind.pop_back();
	}
	return v;
}

ll Poly_area(Point *p, int n){
	ll area = 0;
	for(int i=0;i<n;i++){
		area += floor(Cross(p[i], p[(i+1)%n]) + 0.5);
	}
	return abs(area);
}


int T, n;
Point p[N],pout[N];
Point p2[N], pin[N];



int main(){
	T=read();
	while(T--){
		n=read();
		rec_ind.clear();

		for(int i=0;i<=n+3;i++){
			p[i] = Point();
			p2[i] = Point();
			pout[i] = pin[i] = Point();
		}
		for(int i=0;i<n;i++){
			p[i].scan();
		}

		int nout = Convec_hull(p,n,pout);

		ll area = Poly_area(pout, nout);

		// printf("area = %lld\n",area);
		for(int i=nout;i<nout*2;i++){
			pout[i] = pout[i-nout];
		}
		// pout nout+2?

		// printf("----------\n");
		// for(int i=0;i<nout;i++){
		// 	pout[i].print();
		// }

		sort(rec_ind.begin(), rec_ind.end());
		// p2 = p - pout
		rec_ind.push_back(1000000000);

		int rec_pos = 0;
		int rec_p2=0;
		for(int i=0;i<n;i++){
			if(i==rec_ind[rec_pos]){
				rec_pos++;
				continue;
			}
			p2[rec_p2] = p[i];
			rec_p2++;
		}


		if(rec_p2==0){
			printf("-1\n");
			continue;
		}
		pin[0] = p2[0];

		double dans = 1e20;

		if(rec_p2==1){
			for(int j=0;j<nout;j++){
				Line lout = Line(pout[j],pout[j+1]);
				double dnow = Dis_point_line(pin[0], lout) * Distance(lout.p1, lout.p2) / 2.0;
				dans = min(dans, dnow);
			}

			ll ans = floor(area - dans*2 + 0.5);
			printf("%lld\n",ans);
			continue;
		}

		
		int nin = Convec_hull(p2,n-nout,pin);
		// printf("----------  pin \n");
		// for(int i=0;i<nin;i++){
		// 	pin[i].print();
		// }
		pin[nin] = pin[0];
		
		int ind_out = 0;
		
		Vector v_out(pout[ind_out+1] - pout[ind_out]);
		Line lout = Line(pout[ind_out],pout[ind_out+1]);
		for(int i=0;i<nin;i++){
			Vector v_in(pin[i+1] - pin[i]);
			while(Cross(v_in,v_out)<=0){ // correct?
				double dnow = Dis_point_line(pin[i], lout) * Distance(lout.p1, lout.p2) / 2.0;
				dans = min(dans, dnow);
				ind_out++;
				v_out = Point(pout[ind_out+1] - pout[ind_out]);
				lout = Line(pout[ind_out],pout[ind_out+1]);
			}
		}

		for(int i=nin-1;i<=nin;i++){
			for(int j=0;j<nout;j++){
				Line lout = Line(pout[j],pout[j+1]);
				double dnow = Dis_point_line(pin[i], lout) * Distance(lout.p1, lout.p2) / 2.0;
				dans = min(dans, dnow);
			}
		}

		ll ans = floor(area - dans*2 + 0.5);
		printf("%lld\n",ans);
	}
}

Details

Tip: Click on the bar to expand more detailed information

Test #1:

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

input:

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

output:

40
-1

result:

ok 2 lines

Test #2:

score: -100
Wrong Answer
time: 0ms
memory: 9964kb

input:

10
243
-494423502 -591557038
-493438474 -648991734
-493289308 -656152126
-491185085 -661710614
-489063449 -666925265
-464265894 -709944049
-447472922 -737242534
-415977509 -773788538
-394263365 -797285016
-382728841 -807396819
-373481975 -814685302
-368242265 -818267002
-344482838 -833805545
-279398...

output:

2178418010787347456
1826413114144932608
1651687576234220032
1883871859778999040
2119126281997960192
894016174881844608
2271191316922159360
1998643358049669376
1740474221286618880
1168195646932543232

result:

wrong answer 1st lines differ - expected: '2178418010787347715', found: '2178418010787347456'