QOJ.ac
QOJ
ID | Problem | Submitter | Result | Time | Memory | Language | File size | Submit time | Judge time |
---|---|---|---|---|---|---|---|---|---|
#786568 | #9520. Concave Hull | SZH# | WA | 0ms | 9964kb | C++14 | 4.4kb | 2024-11-26 22:04:16 | 2024-11-26 22:04:17 |
Judging History
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'