tozangezan's diary

勝手にソースコードをコピペして利用しないでください。

AOJ 2167: Find the Point

robustness-hard。いい練習になる。
気をつけないといけないことは、
・点が少ないときのMany
・平行のとき(中点を結んで線を作ろうとすると長さが極端に短くなって誤差る)
・交わるとき(点をいいかげんに選ぶとargを取るときに長さが極端に短くなって誤差る)
最初の3つの直線で候補の点を絞って、これを全探索しました。

#include<stdio.h>
#include<algorithm>
#include<math.h>
#include<vector>
using namespace std;
const double EPS = 1e-6;
/*  */
Pt p1[110];
Pt p2[110];
double rd[100];
double ld[100];
int main(){
	int a;
	while(scanf("%d",&a),a){
		for(int i=0;i<a;i++){
			double X1,X2,Y1,Y2;
			scanf("%lf%lf%lf%lf",&X1,&Y1,&X2,&Y2);
			p1[i]=Pt(X1,Y1);
			p2[i]=Pt(X2,Y2);
		}
		if(a<=2){
			printf("Many\n");continue;
		}
		if(iLL(p1[0],p2[0],p1[1],p2[1])==0&&iLL(p1[1],p2[1],p1[2],p2[2])==0){
			printf("None\n");continue;
		}
		vector<pair<Pt,Pt> >L1;
		vector<pair<Pt,Pt> >L2;
		if(iLL(p1[0],p2[0],p1[1],p2[1])==0){
			Pt L=(p1[0]+p1[1])/2;
			Pt R=(p2[0]+p2[1])/2;
			if((L-R).ABS()<1.0){
				L=(p1[0]+p2[1])/2;
				R=(p2[0]+p1[1])/2;
			}
			L1.push_back(make_pair(L,R));
		}else{
			Pt p=pLL(p1[0],p2[0],p1[1],p2[1]);
			double th=0;
			if((p2[0]-p).ABS()>1)th+=((p2[0]-p).arg());
			else th+=((p1[0]-p).arg());
			if((p2[1]-p).ABS()>1)th+=((p2[1]-p).arg());
			else th+=((p1[1]-p).arg());
			th/=2;
			L1.push_back(make_pair(p,p+Pt(cos(th),sin(th))*1000.0));
			L1.push_back(make_pair(p,p+Pt(cos(th+PI/2),sin(th+PI/2))*1000.0));
		}
		if(iLL(p1[2],p2[2],p1[1],p2[1])==0){
			Pt L=(p1[2]+p1[1])/2;
			Pt R=(p2[2]+p2[1])/2;
			if((L-R).ABS()<1.0){
				L=(p1[2]+p2[1])/2;
				R=(p2[2]+p1[1])/2;
			}
			L2.push_back(make_pair(L,R));
		}else{
			Pt p=pLL(p1[2],p2[2],p1[1],p2[1]);
			double th=0;
			if((p2[2]-p).ABS()>1)th+=((p2[2]-p).arg());
			else th+=((p1[2]-p).arg());
			if((p2[1]-p).ABS()>1)th+=((p2[1]-p).arg());
			else th+=((p1[1]-p).arg());
			th/=2;
			L2.push_back(make_pair(p,p+Pt(cos(th),sin(th))*1000.0));
			L2.push_back(make_pair(p,p+Pt(cos(th+PI/2),sin(th+PI/2))*1000.0));
		}
	//	printf("%d %d\n",L1.size(),L2.size());
		vector<Pt>hb;
		for(int i=0;i<L1.size();i++)for(int j=0;j<L2.size();j++){
		//	if(iLL(L1[i].first,L1[i].second,L2[j].first,L2[j].second)!=1)printf("Alert\n");
			hb.push_back(pLL(L1[i].first,L1[i].second,L2[j].first,L2[j].second));
		}
		int ans=0;
		for(int i=0;i<hb.size();i++){
	//		printf("%f %f: ",hb[i].x,hb[i].y);
			bool dame=false;
			for(int j=0;j<i;j++){
				if((hb[i]-hb[j]).ABS()<EPS){
					dame=true;
				}
			}
			if(dame){
				rd[i]=1;ld[i]=0;continue;
			}
			rd[i]=-999999999;ld[i]=999999999;
			for(int j=0;j<a;j++){
				double dist=dLP(p1[j],p2[j],hb[i]);
				rd[i]=max(rd[i],dist);
				ld[i]=min(ld[i],dist);
			//	printf("%f ",dist);
			}//printf("\n");
			if(rd[i]-ld[i]<EPS)ans++;
		}
		if(ans>1)printf("Many\n");
		else if(ans==0)printf("None\n");
		else{
			for(int i=0;i<hb.size();i++){
				if(rd[i]-ld[i]<EPS)printf("%f %f\n",hb[i].x,hb[i].y);
			}
		}
	}
}