QOJ.ac

QOJ

IDProblemSubmitterResultTimeMemoryLanguageFile sizeSubmit timeJudge time
#373075#4371. Spin DoctorInfinityNSWA 1ms8028kbC++144.4kb2024-04-01 01:54:052024-04-01 01:54:06

Judging History

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

  • [2024-04-01 01:54:06]
  • 评测
  • 测评结果:WA
  • 用时:1ms
  • 内存:8028kb
  • [2024-04-01 01:54:05]
  • 提交

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],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(n==100 && s1==0)printf("s1 before %i\n",s1);

	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(){
	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);

	if(n==100)printf("CH size: %i\n",poly.size());
	//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]);
		//printf("Tangents L(%lld, %lld) R(%lld, %lld)\n",L.x,L.y,R.x,R.y);
		evs.pb({L,-1});
		evs.pb({-R,1});
		if(cand[i].y>=mny && cand[i].y<=mxy)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: 1ms
memory: 8028kb

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: 0
Accepted
time: 0ms
memory: 7728kb

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:

8

result:

ok single line: '8'

Test #3:

score: 0
Accepted
time: 1ms
memory: 7932kb

input:

5
5 7 0
3 4 0
5 7 0
5 7 1
9 4 0

output:

1

result:

ok single line: '1'

Test #4:

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

input:

100
7487 4751 1
7499 5064 1
7471 5376 1
7404 5683 1
7300 5979 1
7159 6260 1
6984 6520 1
6777 6757 1
6543 6966 1
6284 7144 1
6006 7288 1
5711 7396 1
5405 7466 1
5092 7498 1
4780 7490 1
4469 7442 1
4167 7357 1
3878 7234 1
3607 7075 1
3358 6884 1
3135 6664 1
2941 6417 1
2780 6147 1
2653 5860 1
2564 555...

output:

CH size: 50
51

result:

wrong answer 1st lines differ - expected: '61', found: 'CH size: 50'