QOJ.ac

QOJ

IDProblemSubmitterResultTimeMemoryLanguageFile sizeSubmit timeJudge time
#373114#4371. Spin DoctorInfinityNSWA 2ms7708kbC++144.3kb2024-04-01 02:41:082024-04-01 02:41:09

Judging History

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

  • [2024-04-01 02:41:09]
  • 评测
  • 测评结果:WA
  • 用时:2ms
  • 内存:7708kb
  • [2024-04-01 02:41:08]
  • 提交

answer

#include <bits/stdc++.h>
using namespace std;
#define ll long long
#define pb push_back
#define mp make_pair

struct pt{
	ll x,y;

	pt():x(0),y(0){}
	pt(ll a,ll b):x(a),y(b){}
};

pt operator - (pt a,pt b){return pt(a.x-b.x,a.y-b.y);}
pt operator - (pt a){return pt(-a.x,-a.y);}

ll cross(pt a,pt b){return a.x*b.y-a.y*b.x;}
ll dot(pt a,pt b){return a.x*b.x+a.y*b.y;}

int part(pt a){return a.y<0 || (a.y==0 && a.x<0);}
bool operator < (pt a,pt b){return mp(part(a),(ll)0)<mp(part(b),cross(a,b));}
bool operator == (pt a,pt b){return mp(a.x,a.y)==mp(b.x,b.y);}

int sgn(ll x){return x==0?0:(x<0?-1:1);}

const int N=250050;
pt pts[N];
int c[N];

bool cmp(pt a,pt b){return mp(a.x,a.y)<mp(b.x,b.y);}
vector<pt> ConvexHull(vector<pt> poly){
	sort(poly.begin(),poly.end(),cmp);
	poly.erase(unique(poly.begin(),poly.end()),poly.end());
	if(poly.size()<2)return poly;
	vector<pt> hull;
	int sz=0;
	for(int t=0;t<2;t++){
		int was=sz;
		for(auto p:poly){
			while(sz>was+1 && cross(hull[sz-1]-hull[sz-2],p-hull[sz-2])<=0){
				hull.pop_back();
				sz--;
			}
			hull.pb(p);
			sz++;
		}
		hull.pop_back();
		sz--;
		reverse(poly.begin(),poly.end());
	}
	return hull;
}

bool OnSeg(pt a,pt b,pt p){
	pt v=b-a;
	if(cross(v,p-a)!=0)return false;
	ll da=dot(v,a);
	ll dp=dot(v,p);
	ll db=dot(v,b);
	return da<=dp && dp<=db;
}

bool InTriangle(pt a,pt b,pt c,pt p){
	vector<pt> poly={a,b,c};
	bool lo=false,hi=false;
	for(int i=0;i<3;i++){
		ll cr=cross(poly[i]-p,poly[(i+1)%3]-p);
		if(cr<0)lo=true;
		if(cr>0)hi=true;
	}
	return !lo || !hi;
}

bool Inside(vector<pt>& poly, pt p){
	if(poly.size()==1)return p==poly[0];
	if(poly.size()==2)return OnSeg(poly[0],poly[1],p);
	int bot=0,top=(int)poly.size()-3,ans=0;
	while(bot<=top){
		int mid=top+bot>>1;
		if(cross(poly[mid]-poly.back(),p-poly.back())>=0){
			bot=mid+1;
			ans=mid;
		}else{
			top=mid-1;
		}
	}
	//printf("Inside? %i\n",ans);
	return InTriangle(poly[ans],poly[ans+1],poly.back(),p);
}

pt Solve(vector<pt>& poly,pt p,int l,int r,int sg){
	int bot=l,top=r-1,ans=r;
	while(bot<=top){
		int mid=bot+top>>1;
		if(sgn(cross(poly[mid]-p,poly[mid+1]-p))==sg){
			bot=mid+1;
			ans=mid;
		}else{
			top=mid-1;
		}
	}
	//printf("Solve (%lld, %lld) l:%i r:%i -- %i (%lld, %lld)\n",p.x,p.y,l,r,ans,poly[ans].x,poly[ans].y);
	return poly[ans]-p;
}

pair<pt,pt> Tangents(vector<pt>& poly, pt p){
	if(poly.size()==1)return {poly[0]-p,poly[0]-p};
	if(poly.size()==2){
		if(cross(poly[0]-p,poly[1]-p)>=0)return {poly[0]-p,poly[1]-p};
		else return {poly[1]-p,poly[0]-p};
	}
	int bot=1,top=(int)poly.size()-2,ans=0;
	int s1=sgn(cross(poly.back()-p,poly.front()-p));
	while(top>=bot){
		int mid=top+bot>>1;
		if(sgn(cross(poly.back()-p,poly[mid]-p))==s1){
			ans=mid;
			bot=mid+1;
		}else{
			top=mid-1;
		}
	}
	//printf("Split\n");
	//for(int i=0;i<=ans;i++)printf("(%lld, %lld) ",poly[i].x,poly[i].y);printf("\n");
	//for(int i=ans+1;i<poly.size();i++)printf("(%lld, %lld) ",poly[i].x,poly[i].y);printf("\n");
	if(s1==0)s1=-sgn(cross(poly.back()-p,poly[ans+1]-p));
	pt L=Solve(poly,p,0,ans,-s1);
	pt R=Solve(poly,p,ans+1,(int)poly.size()-1,s1);
	if(s1==-1)swap(L,R);
	return {L,R};
}

int main(){
	int n;
	scanf("%i",&n);
	vector<pt> poly;
	for(int i=1;i<=n;i++){
		scanf("%lld %lld %i",&pts[i].x,&pts[i].y,&c[i]);
		if(c[i]==1)poly.pb(pts[i]);
	}
	if(poly.size()==1){
		printf("1\n");
		return 0;
	}
	poly=ConvexHull(poly);

	//printf("Convex hull: ");
	//for(pt p:poly)printf("(%lld, %lld) ",p.x,p.y);
	//printf("\n");

	ll mny=poly[0].y,mxy=poly[0].y;
	for(int i=1;i<poly.size();i++){
		mny=min(mny,poly[i].y);
		mxy=max(mxy,poly[i].y);
	}
	int cnt=0;
	vector<pt> cand;
	for(int i=1;i<=n;i++){
		if(Inside(poly,pts[i])){
			//printf("%i(%lld, %lld) is inside\n",i,pts[i].x,pts[i].y);
			cnt++;
		}else{
			cand.pb(pts[i]);
		}
	}
	vector<pair<pt,int>> evs;
	for(int i=0;i<cand.size();i++){
		//printf("Cand (%lld, %lld)\n",cand[i].x,cand[i].y);
		pt L,R;
		tie(L,R)=Tangents(poly,cand[i]);
		if(part(L))L=-L;
		if(part(R))R=-R;
		//printf("Tangents L(%lld, %lld) R(%lld, %lld)\n",L.x,L.y,R.x,R.y);
		evs.pb({R,-1});
		evs.pb({L,1});
		if(L<R)cnt++;
	}
	int ans=cnt;
	sort(evs.begin(),evs.end());
	for(auto ev:evs){
		cnt-=ev.second;
		ans=min(ans,cnt);
	}
	printf("%i\n",ans);
	return 0;
}

Details

Tip: Click on the bar to expand more detailed information

Test #1:

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

input:

6
0 10 0
10 0 1
12 8 1
5 5 0
11 2 1
11 3 0

output:

4

result:

ok single line: '4'

Test #2:

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

input:

10
6 1 1
0 2 0
2 1 1
6 1 1
8 2 0
4 4 0
4 0 0
2 3 1
6 1 0
6 3 1

output:

7

result:

wrong answer 1st lines differ - expected: '8', found: '7'