nyoj 82 迷宫寻宝(二)

http://acm.nyist.net/JudgeOnline/problem.php?pid=83php

 

题目解法主要在于判断两线段是否相交,思路是穷举全部地图四周的点,其中每个边界上的点和终点构成一个线段, 求出全部线段和墙相交的最少次数就是结果.net

#include<stdio.h>
struct point
{
	double x, y;
};
struct line
{
	point a, b;
};
double det(double x1, double y1, double x2, double y2)//计算叉积
{
	return x1 * y2 - x2 * y1;
}
double get_dir(point a, point b, point c)//计算向量ac 在向量ab的哪一个方向(正数为逆时针,负数为顺时针, 零为同向或者反向)
{
	return det(b.x - a.x, b.y - a.y, c.x - a.x, c.y - a.y);
}
int check_cross(line a, line b)//计算出两条线段是否相交,注意只有肯定两条线段的都在对方的两侧,才能肯定这两条线段相交
{
	double flag1 = get_dir(a.a, a.b, b.a) * get_dir(a.a, a.b, b.b);
	int f1 = flag1 > 0 ? 1 : -1;
	double flag2 = get_dir(b.a, b.b, a.a) * get_dir(b.a, b.b, a.b);
	int f2 = flag2 > 0? 1 : -1;
	if(f1 < 0 && f2 < 0)
		return -1;
	else
		return 1;
}
line lines[40];
int axis1[101], axis2[101], axis3[101], axis4[101];
int get_cross_number(point start, point end, int total)//计算相交次数
{
	line templine;
	templine.a = start;
	templine.b = end;
	int count = 0;
	int i;
	for(i = 0; i < total; i++)
	{
		if(check_cross(templine, lines[i]) - 0 < 1e-6)
			count ++;
	}
	return count;
}
int main()
{
	int n;
	scanf("%d", &n);
	while(n--)
	{
		
		int m;
		int top1, top2, top3, top4;
		top1 = top2 = top3 = top4 = 0;
		scanf("%d", &m);
		int i;
		for(i = 0; i < m; i++)
		{
			int x1, x2, y1, y2;
			scanf("%d %d %d %d", &x1, &y1, &x2, &y2);
			lines[i].a.x = x1;
			lines[i].a.y = y1;
			lines[i].b.x = x2;
			lines[i].b.y = y2;
		}
		point end;
		scanf("%lf %lf", &end.x, &end.y);
		int min = 0x7fffffff;
		for(i = 0; i < 101; i++)
		{
			if(min == 0)
				break;
			point start;
			int res;
			start.x = 0;
			start.y = i;
			res = get_cross_number(start, end, m);
			if(res < min)
				min = res;
			start.x = 100;
			start.y = i;
			res = get_cross_number(start, end, m);
			if(res < min)
				min = res;
			start.x = i;
			start.y = 0;
			res = get_cross_number(start, end, m);
			if(res < min)
				min = res;
			start.x = i;
			start.y = 100;
			res = get_cross_number(start, end, m);
			if(res < min)
				min = res;
		}
		printf("%d\n", min + 1);
	}
	return 0;
}
相关文章
相关标签/搜索