QOJ.ac
QOJ
ID | Problem | Submitter | Result | Time | Memory | Language | File size | Submit time | Judge time |
---|---|---|---|---|---|---|---|---|---|
#34453 | #868. Friendship Circles | Froggygua | WA | 35ms | 3724kb | C++17 | 6.1kb | 2022-06-09 10:28:52 | 2022-06-09 10:28:53 |
Judging History
answer
#include<bits/stdc++.h>
using namespace std;
const double eps=1e-9;
const double PI=acos(-1.0);
const double inf=1e10+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];
}
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;
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()+p[i],i);
}
auto A=_HPI(L);
vector<int> ans;
for(auto t:A){
if(t.id>=1){
ans.push_back(t.id);
}
}
cout<<ans.size()<<' ';
sort(ans.begin(),ans.end());
for(auto x:ans){
cout<<x<<' ';
}
cout<<'\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;
}
Details
Tip: Click on the bar to expand more detailed information
Test #1:
score: 100
Accepted
time: 0ms
memory: 3688kb
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: 35ms
memory: 3724kb
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 3 1 2 3 6 1 2 3 4 5 6 5 1 2 3 4 9 4 1 2 3 4 6 1 2 3 4 5 9 2 1 2 3 1 4 6 5 2 4 5 6 7 4 1 2 4 5 3 1 2 3 3 2 3 6 3 1 6 8 1 1 2 1 2 5 1 3 4 6 7 5 1 2 4 5 6 3 2 3 4 4 1 3 4 7 4 1 3 7 9 3 3 4 5 4 3 4 6 8 5 1 3 4 6 7 3 1 2 3 2 2 3 3 2 5 6 ...
result:
wrong answer 71st numbers differ - expected: '4', found: '3'