NYOJ142——管道问题

题目链接:

题目分析:先不分析了,还没有搞出来,矬人~

代码:

#include<stdio.h>
#include<math.h>

typedef struct  
{
	double x;
	double y;
}POINT;

typedef struct  
{
	POINT p1;
	POINT p2;
}LINE;

inline double CrossProduct(POINT *p1, POINT *p2, POINT *p3)
{
	return (p2->x - p1->x) * (p2->y - p3->y) - (p2->x - p3->x) * (p2->y - p1->y);
}

inline double min(const double a, const double b)
{
	return a < b ? a : b;
}

inline double max(const double a, const double b)
{
	return a > b ? a : b;
}

inline bool InSegment(POINT *p, LINE *l)
{//判断点是否在线段中
	if(p->x > min(l->p1.x, l->p2.x) && p->x < max(l->p1.x, l->p2.x)
		&& p->y > min(l->p1.y, l->p2.y) && p->y < max(l->p1.y, l->p2.y))
		return true;
	else
		return false;
}

bool SegmentIntersect(LINE *l1, LINE *l2)
{//判断两个线段是否相交,第一个是判断是否相交,后面四个if是判断其中一个线段是否包含了另一个线段的端点
	double d1 = CrossProduct(&l1->p1, &l1->p2, &l2->p1);
	double d2 = CrossProduct(&l1->p1, &l1->p2, &l2->p2);
	double d3 = CrossProduct(&l2->p1, &l2->p2, &l1->p1);
	double d4 = CrossProduct(&l2->p1, &l2->p2, &l1->p2);
	if( ((d1 < 0 && d2 > 0) || (d1 > 0 && d2 < 0)) && 
		((d3 < 0 && d4 > 0) || (d3 > 0 && d4 < 0)))
		return true;
	else if(fabs(d1) < 0.0000001 && InSegment(&l2->p1, l1))
		return true;
	else if(fabs(d2) < 0.0000001 && InSegment(&l2->p2, l1))
		return true;
	else if(fabs(d3) < 0.0000001 && InSegment(&l1->p1, l2))
		return true;
	else if(fabs(d4) < 0.0000001 && InSegment(&l1->p2, l2))
		return true;
	else
		return false;
}

double GetPoint(LINE *l1, LINE *l2)//应该是这里有问题,但感觉又没找到问题
{
	return (l1->p1.x * (l1->p2.y - l1->p1.y) / (l1->p2.x - l1->p1.x) - l2->p1.x * (l2->p2.y - l2->p1.y) / (l2->p2.x - l2->p1.x) +
		(l2->p1.y - l1->p1.y)) / ((l1->p2.y - l1->p1.y) / (l1->p2.x - l1->p1.x) - (l2->p2.y - l2->p1.y) / (l2->p2.x - l2->p1.x));
}

double GetIntersect(LINE *l, int n)
{//求交点数
	double i,j;
	int k;
	LINE line;
	double x,ans;
	double temp;

	line.p1.x = l[0].p1.x;
	line.p2.x = l[n - 1].p2.x;
	ans = line.p1.x;
	for(i = l[1].p1.y + 0.01; i < l[0].p1.y; i += 0.01)
	{
		line.p1.y = i;
		for(j = l[n - 1].p2.y + 0.01; j < l[n - 2].p2.y; j += 0.01)
		{
			line.p2.y = j;
			x = line.p2.x;
			for(k = 0; k < n; k += 2)
			{
				if(SegmentIntersect(&line,&l[k]))
					x = min(x, GetPoint(&line, &l[k]));
				if(SegmentIntersect(&line, &l[k + 1]))
					x = min(x, GetPoint(&line, &l[k + 1]));
				if(x < line.p2.x)
					break;
			}
			ans = max(ans, x);
		}
	}

	if(ans <= line.p1.x || ans >= line.p2.x)
		return -1;
	else
		return ans;
}

int main()
{
	int n;
	int i,ans;
	LINE line[40];

	while(scanf("%d",&n) && n)
	{
		--n;
		n *= 2;
		//输入第一条线段
		scanf("%lf %lf %lf %lf", &line[0].p1.x, &line[0].p1.y, &line[0].p2.x, &line[0].p2.y);
		line[1].p1.x = line[0].p1.x;
		line[1].p1.y = line[0].p1.y - 1;
		line[1].p2.x = line[0].p2.x;
		line[1].p2.y = line[0].p2.y - 1;
		for(i = 2; i < n; i += 2)
		{
			//输入当前线段的终点,起点是前一个线段
			scanf("%lf %lf", &line[i].p2.x, &line[i].p2.y);
			line[i].p1.x = line[i - 2].p2.x;
			line[i].p1.y = line[i - 2].p2.y;
			line[i + 1].p1.x = line[i].p1.x;
			line[i + 1].p1.y = line[i].p1.y - 1;
			line[i + 1].p2.x = line[i].p2.x;
			line[i + 1].p2.y = line[i].p2.y - 1;
		}

		ans = GetIntersect(line, n);
		if(ans == -1)
			printf("Through all the pipe.\n");
		else
			printf("%.2lf\n",ans);
	}
}
  • 2
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值