POJ-Rohr (Geometrie)

  • Rohr
  • Die Bedeutung
    der Frage ist ein gekrümmtes Rohr, die Koordinaten jedes oberen Wendepunkts sind angegeben, und der Start- und Endpunkt werden auch als Wendepunkte betrachtet. Die y-Koordinate des unteren Wendepunkts ist die y-Koordinate des oberen Wendepunkts -1, und die x-Koordinate bleibt unverändert. Wenn ein Strahl vom linken Ende des Rohrs emittiert wird, welche x-Koordinate kann der Strahl am weitesten erreichen?
  • Bei
    dieser Frage habe ich die Grenzwertmethode in Betracht gezogen, dh das am weitesten entfernte Licht muss zwei Wendepunkte passieren (kann sowohl obere Wendepunkte oder beide unteren Wendepunkte sein oder ein oberer Wendepunkt und ein unterer Wendepunkt), natürlich ist das am weitesten entfernte Licht mehr als einer. Es muss jedoch eine Linie geben, die durch zwei Wendepunkte verläuft (die durch Translation erhalten werden kann), und dann die durch die beiden Wendepunkte gebildete gerade Linie aufzählen, um festzustellen, ob sie legal ist. Wenn sie legal ist, finden Sie die am weitesten entfernte x-Koordinate, die sie erreichen kann. Wie kann man beurteilen, ob die Linie das Rohr schneidet? Ich finde die entsprechende y-Koordinate und vergleiche sie mit der y-Koordinate des oberen und unteren Wendepunkts. Wenn sie größer als das Maximum oder kleiner als das Minimum ist, gibt es einen Schnittpunkt. Dann finde ich die x-Koordinate des Schnittpunkts und aktualisiere die Antwort.
#pragma GCC optimize(2)
//#include<bits/stdc++.h>
#include<iostream>
#include<cstdio>
#include<string>
#include<cmath>
using namespace std;

typedef long long ll;
typedef unsigned long ul;
typedef unsigned long long ull;
#define pi acos(-1.0)
#define e exp(1.0)
#define pb push_back
#define mk make_pair
#define fir first
#define sec second
#define scf scanf
#define prf printf
typedef pair<ll,ll> pa;
const int dir_4[4][2]={
    
    -1,0,0,1,1,0,0,-1};
const int dir_8[8][2]={
    
    -1,-1,-1,0,-1,1,0,1,1,1,1,0,1,-1,0,-1};
const ll INF=0x3f3f3f3f3f3f3f3f;
const int MAX_N=50;
bool all;
const double eps=1e-8;
double res;
int N;
struct node{
    
    
	double x,y;
}pos[2][MAX_N];//pos[0][]存的是上界的拐点,pos[1][]存的是下界的拐点 
double do_x(node a,node b,node c,node d){
    
    //求能够到达的最大的x 
	double a1,b1,c1,a2,b2,c2;
	a1=b.y-a.y;a2=d.y-c.y;
	b1=a.x-b.x;b2=c.x-d.x;
	c1=b.x*a.y-a.x*b.y;c2=d.x*c.y-c.x*d.y;
	double x=(b1*c2-b2*c1)/(b2*a1-b1*a2);//除数是不可能为0的,不存在平行 
	return x;
}
double do_y(double x,node a,node b){
    
    //求直线在x的y坐标 
	double y=a.y-(a.x-x)*(b.y-a.y)/(b.x-a.x);
	return y;
}
void do_(int pre,int bk_p,int nex,int bk_n){
    
    
	int i,j,k;
	int du=-1,flag=-1;
	for(i=1;i<=N;i++){
    
    
		double y=do_y(pos[0][i].x,pos[bk_p][pre],pos[bk_n][nex]);
		if(y>pos[0][i].y&&fabs(y-pos[0][i].y)>eps){
    
    //一开始没有加eps,被卡精度了 
			du=i;
			flag=0;
			break;
		}
		if(y<pos[1][i].y&&fabs(y-pos[1][i].y)>eps){
    
    
			du=i; 
			flag=1;
			break;
		}
	}
	if(du==-1){
    
    //与所有的管道上下界都没有交叉,通过整个管道 
		all=1;
		return ;
	}
	if(du<=nex)//交叉部分在这nex之前,直接return
	return ;
	if(!flag)//与管道的上界交叉 
	res=max(res,do_x(pos[bk_p][pre],pos[bk_n][nex],pos[0][i-1],pos[0][i]));
	else // 与管道的下界交叉 
	res=max(res,do_x(pos[bk_p][pre],pos[bk_n][nex],pos[1][i-1],pos[1][i]));
	return ;
} 
int main()
{
    
    
//  freopen(".../.txt","w",stdout);
//  freopen(".../.txt","r",stdin);
//	ios::sync_with_stdio(false);
	while(scf("%d",&N)&&N){
    
    
		int i,j,k;
		double x,y;
		all=0;
		for(i=1;i<=N;i++){
    
    
			scf("%lf %lf",&pos[0][i].x,&pos[0][i].y);
			pos[1][i].x=pos[0][i].x;
			pos[1][i].y=pos[0][i].y-1;
		}
		res=pos[0][1].x;
		for(i=1;i<N;i++){
    
    //枚举该光线上的左拐点 
			if(all)
			break;
			//pre是上界的拐点
			for(j=i+1;j<=N;j++){
    
    // 枚举该光线上的右拐点 
				if(all)
				break;
				//nex是上界的点
				do_(i,0,j,0);					
				//nex是下jie的点
			 	do_(i,0,j,1);
			} 
			//pre是下jie的点
			for(j=i+1;j<=N;j++){
    
    //枚举该光线上的右拐点 
				if(all)
				break;
				//nex是上界的点
				do_(i,1,j,0);
				//nex是下jie的点
				do_(i,1,j,1);
			}
		}
		if(all)
		prf("Through all the pipe.\n");
		else
		prf("%.2f\n",res);
	}
	return 0;
}

Ich denke du magst

Origin blog.csdn.net/weixin_43311695/article/details/109158203
Empfohlen
Rangfolge