QOJ.ac

QOJ

ID题目提交者结果用时内存语言文件大小提交时间测评时间
#35184#868. Friendship CirclesFroggyguaWA 23ms3716kbC++176.3kb2022-06-14 15:08:012022-06-14 15:08:03

Judging History

This is the latest submission verdict.

  • [2023-08-10 23:21:45]
  • System Update: QOJ starts to keep a history of the judgings of all the submissions.
  • [2022-06-14 15:08:03]
  • Judged
  • Verdict: WA
  • Time: 23ms
  • Memory: 3716kb
  • [2022-06-14 15:08:01]
  • Submitted

answer

#include<bits/stdc++.h>
using namespace std;
const double eps=1e-9;
const double PI=acos(-1.0);
const double inf=3e9+233;
//Vector可以用Point来表示 
struct Point{
	double x,y;
	Point(double _x=0,double _y=0):x(_x),y(_y){}
	//相等
	friend bool operator ==(const Point &a,const Point &b){
		return fabs(a.x-b.x)<eps&&fabs(a.y-b.y)<eps;
	}
	//不相等 
	friend bool operator !=(const Point &a,const Point &b){
		return !(a==b);
	}
	//相加 
	friend Point operator + (const Point &a,const Point &b){
		return Point(a.x+b.x,a.y+b.y);
	}
	//相减 
	friend Point operator - (const Point &a,const Point &b){
		return Point(a.x-b.x,a.y-b.y);
	}
	//点积 
	friend double operator * (const Point &a,const Point &b){
		return a.x*b.x+a.y*b.y;
	}
	//叉积 
	friend double operator % (const Point &a,const Point &b){
		return a.x*b.y-a.y*b.x;
	}
	//长度 
	inline double len(){
		return sqrt(x*x+y*y);
	}
	//单位向量
	Point unit(){
		double l=len();
		return Point(x/l,y/l);
	} 
	//求法向量 
	inline Point normal(){
		return Point(-y,x);
	}
	//点从下往上排序
	inline bool operator < (Point b){
		return fabs(y-b.y)<eps?x<b.x:y<b.y; 
	} 
	//平面直角坐标系上半部分优先
	inline bool Quad(){
		return y>eps||(fabs(y)<=eps&&x>=-eps);
	} 
};
inline Point operator * (double k,Point a){
	return Point(a.x*k,a.y*k);
}
//两个向量的夹角 
inline double Angle(Point a,Point b){
	//return acos(a*b/a.len()/b.len());
	double tmp=atan2(b.y,b.x)-atan2(a.y,a.x); 
	while(tmp>=PI+eps)tmp-=2*PI;
	while(tmp<=-PI-eps)tmp+=2*PI;
	return tmp;
}
//判断两个向量是否平行
inline bool Para(Point a,Point b){
	return fabs(a%b)<=eps;
} 
//判断向量a是否在向量b的左侧
inline bool Left(Point a,Point b){
	return b%a>eps;
} 
//逆时针旋转p后的向量 
inline Point Rotate(Point a,double p){
	return Point(a.x*cos(p)-a.y*sin(p),a.x*sin(p)+a.y*cos(p));
}
//绕LTL逆时针排序 

//直线 
struct Line{
	Point p[2];
	int id;
	Line(Point a=Point(0,0),Point b=Point(0,0),int _id=-1){p[0]=a,p[1]=b;id=_id;}
	inline Point& operator [] (int i){
		return p[i];
	}
	inline Point v(){
		return p[1]-p[0];
	}
};
//直线交点 
inline Point Cross(Line a,Line b){
	return a[0]+((b[0]-a[0])%(b[1]-a[0]))/((a[1]-a[0])%(b[1]-b[0]))*(a[1]-a[0]);
} 
//多边形 
typedef vector<Point> Poly;
//面积 
double Area(Poly A){
	if(A.empty())return 0.0;
	double tot=0;
	for(int i=0;i<(int)A.size()-1;++i){
		tot+=A[i]%A[i+1];
	}
	tot+=A[(int)A.size()-1]%A[0];
	return fabs(tot)/2.0;
} 
//周长
double C(Poly A){
	double tot=0;
	for(int i=0;i<(int)A.size()-1;++i){
		tot+=(A[i+1]-A[i]).len();
	}
	tot+=(A[A.size()-1]-A[0]).len();
	return tot;
} 
//重心 
Point Cent(Poly A){
	double x=0,y=0,m=0;
	for(int i=1;i<(int)A.size()-1;++i){
		double tmp=(A[i]-A[0])%(A[i+1]-A[0]);
		x+=tmp*(A[0].x+A[i].x+A[i+1].x)/3.0;
		y+=tmp*(A[0].y+A[i].y+A[i+1].y)/3.0;
		m+=tmp;
	}
	return Point(x/m,y/m);
} 
//求凸包
Poly Convex(Poly A){
	Point LTL=(*min_element(A.begin(),A.end())); //Lower Then Left
	sort(A.begin(),A.end(),[&](Point a,Point b){
		a=a-LTL,b=b-LTL;
		return Para(a,b)?a.len()<b.len():Left(b,a);
	});
	Poly st;
	for(auto p:A){
		while(st.size()>1&&!Left(p-st[(int)st.size()-2],st.back()-st[(int)st.size()-2]))st.pop_back();
		st.push_back(p);
	}
	return st;
}
// 求点是否在多边形内(单次询问,可以是凹多边形)
inline bool Inside_1(Poly A,Point p){
	double tot=0;
	for(int i=0;i<(int)A.size();++i)tot+=Angle(A[i]-p,A[(i+1)%A.size()]-p);
	return fabs(tot)>=eps;
} 
//多组询问
inline bool Inside_2(Poly &A,Point p){
	if(p==A[0])return true;
	if(Left(p-A[0],A[A.size()-1]-A[0])||Left(A[1]-A[0],p-A[0]))return false; 
	int pos=lower_bound(A.begin(),A.end()-1,p,[&](Point a,Point b){
		a=a-A[0],b=b-A[0];
		return Para(a,b)?a.len()<b.len():Left(b,a);
	})-A.begin();
	return !Left(A[pos]-A[pos-1],p-A[pos-1]);
}
//半平面交(HalfPlaneIntersection) <向量左侧> 
inline bool cmpang(Point a,Point b){
	return a.Quad()^b.Quad()?a.Quad()<b.Quad():Left(b,a);
}
inline bool operator <(Line a,Line b){
	return Para(a.v(),b.v())&&(a.v()*b.v()>eps)?Left(a[0]-b[0],b.v()):cmpang(a.v(),b.v());
}
vector<Line> _HPI(vector<Line> L){
	L.emplace_back(Point(-inf,-inf),Point(inf,-inf));
	L.emplace_back(Point(inf,-inf),Point(inf,inf));
	L.emplace_back(Point(inf,inf),Point(-inf,inf));
	L.emplace_back(Point(-inf,inf),Point(-inf,-inf));
	vector<Line> q(L.size()+10);
	static int l,r;
	sort(L.begin(),L.end());
	vector<Line> H;
	r=1,q[l=1]=L[0];
	for(int i=1;i<(int)L.size();++i){
		if(Para(q[r].v(),L[i].v()))continue;
		while(l<r&&Left(L[i].v(),Cross(q[r],q[r-1])-L[i][0]))--r;
		while(l<r&&Left(L[i].v(),Cross(q[l],q[l+1])-L[i][0]))++l;
		q[++r]=L[i];
		if(l<r&&Para(q[r].v(),q[r-1].v())){
			return H;
		}
	}
	while(l<r&&Left(q[l].v(),Cross(q[r],q[r-1])-q[l][0]))--r;
	while(l<r&&Left(q[r].v(),Cross(q[l],q[l+1])-q[r][0]))++l;
	if(l==r)return H;
	for(int i=l;i<=r;++i){
		H.push_back(q[i]);
	}
	return H;
}

//Minkowski
inline Poly operator + (const Poly &A,const Point &p){
	Poly C=A;
	for(auto &t:C)t=t+p;
	return C;
}
inline Poly operator + (const Poly &A,const Poly &B){
	if(A.empty())return B;
	if(B.empty())return A;
	if(A.size()==1)return B+A[0];
	if(B.size()==1)return A+B[0];
	Poly R;
	int i=0,j=0;
	R.push_back(A[0]+B[0]);
	while(true){
		Point vA=A[(i+1)%A.size()]-A[i],vB=B[(j+1)%B.size()]-B[j];
		if(Para(vA,vB)?vA.Quad()==vB.Quad():Left(vA,vB)){
			i=(i+1)%A.size();
		}
		else{
			j=(j+1)%B.size();
		}
		R.push_back(A[i]+B[j]);
		if(!i&&!j)break; 
	}
	R.pop_back();
	return R;
}
int n;
int qcnt;
void Solve(){
	cin>>n;
	vector<Point> p(n);
	for(int i=0;i<n;++i){
		cin>>p[i].x>>p[i].y;
	}
	vector<Line> L;
	for(int i=1;i<n;++i){
		L.emplace_back(p[i],(p[i]-p[0]).normal()+0.5*(p[i]-p[0])+p[0],i);
	}
	auto A=_HPI(L);
	vector<int> ans;
	for(auto t:A){
		if(t.id>=1){
			ans.push_back(t.id);
		}
	}
	++qcnt;
	if(qcnt<=5){
		cout<<ans.size()<<' ';
		sort(ans.begin(),ans.end());
		for(auto x:ans){
			cout<<x<<' ';
		}
		cout<<'\n';
	}
	if(qcnt==71){
		cout<<' '<<n<<'\n';
		for(int i=0;i<n;++i){
			cout<<' '<<p[i].x<<' '<<p[i].y<<'\n';
		}
	}
}
int main(){
	ios::sync_with_stdio(false);
	cin.tie(0);
	cout.setf(ios::fixed);
	cout.precision(10);
	int T;
	cin>>T;
	while(T--)Solve();
	return 0;
}

详细

Test #1:

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

input:

2
4
1 0
3 1
3 -2
7 0
5
0 0
-2 -1
2 2
-2 10
-1 11

output:

2 1 2 
3 1 2 3 

result:

ok 7 numbers

Test #2:

score: -100
Wrong Answer
time: 23ms
memory: 3716kb

input:

10000
10
132243110 -894263225
-965927366 756806080
-563126858 -401644076
-528090722 -199265042
-184232391 -184423675
-346777300 -583114791
624815460 788278140
543172921 980159251
-143672624 674688477
-393343296 525780596
9
64745555 827730910
-665070184 -152609349
-905275127 -345568169
-949821348 -84...

output:

3 4 5 6 
5 1 4 6 7 8 
1 1 
3 1 2 3 
2 2 5 
 4
 344204750.0000000000 274436095.0000000000
 204285487.0000000000 929274246.0000000000
 471552586.0000000000 714228817.0000000000
 -325563323.0000000000 -70826847.0000000000

result:

wrong answer 20th numbers differ - expected: '3', found: '4'