poj 2704

题意:从一条线段(property)上观察另一与之平行的线段(house),其中有很多与它们都平行的线段(障碍物),求在property得可见整条线段house的最长连续范围的长度。

初时的想法是,求出在哪些点的范围可以看到整个HOUSE。 后来在DIS上找了几组数据,就变得都要特判了。再想想,既然找可行点不行,就找不可行的点,就是在哪些点的范围不能看到整个HOUSE。这样,代码就简化了。

#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <cmath>

using namespace std;

int n;
const double eps=0.00000001;
struct point{
	double x,y;
}st,en;
struct line{
	point start,end;
}obst[200],house,pl;
struct xcor{
	double p;
	int flag;
	xcor(){ flag=0;}
}xx[1200];
int xxc; double tmp;

void slove(point s, point t){
	if(s.x==t.x){
	tmp=t.x;
	}
	else{
	double k=(s.y-t.y)/(s.x-t.x);
	tmp=(pl.start.y-s.y)/k+s.x;
	}
	if(tmp>pl.end.x) tmp=pl.end.x;
	if(tmp<pl.start.x) tmp=pl.start.x;
}

bool cmp(xcor A,xcor B){
	if(A.p<B.p)return true;
	else if(A.p==B.p){
		if(A.flag<B.flag)return true;
	}
	return false;
}

int main(){
	double a,b,c;
	while(cin>>a>>b>>c){
		if(a==0&&b==0&&c==0) break;
		xxc=0;
		st.x=a; st.y=c; en.x=b; en.y=c;
		house.start=st; house.end=en;
		cin>>a>>b>>c;
		st.x=a; st.y=c; en.x=b; en.y=c;
		pl.start=st; pl.end=en;
		cin>>n; 
		int co=0;
		for(int i=0;i<n;i++){
			cin>>a>>b>>c;
			if(c<house.start.y&&c>pl.start.y){
			st.x=a; st.y=c; en.x=b; en.y=c;
			obst[co].start=st; obst[co].end=en;
			co++;
			}
		}
		n=co;
		for(int i=0;i<n;i++){
			slove(house.end,obst[i].start);
			xx[xxc].p=tmp; xx[xxc].flag=-1;
			xxc++;
			slove(house.start,obst[i].end);
			xx[xxc].p=tmp; xx[xxc].flag=1;
			xxc++;
		}
		sort(xx,xx+xxc,cmp);
		int now=0; double pre,lo,tt;
		pre=pl.start.x; lo=0; 
		for(int i=0;i<xxc;i++){
			if(now==0){
				tt=xx[i].p-pre;
				if(tt>lo) lo=tt;
			}
			now+=xx[i].flag;
			pre=xx[i].p;
		}
		tt=pl.end.x-pre;
		if(tt>lo) lo=tt;
		if(lo>0)
		printf("%0.2lf\n",lo);
		else printf("No View\n");
	}
}

  

posted @ 2014-07-29 20:33  chenjunjie1994  阅读(343)  评论(0编辑  收藏  举报