zoj 1472 Overlapping Shapes

这题关键在于怎么判断圆和长方形是否相交
只需计算 圆心到长方形的最大距离maxd和最小距离mind
然后 1、如果maxd<r那么显然内含 2、如果mind>r显然分离 3、其他情况就是相交的情况

#include<iostream>
#include<stdlib.h>
#include<math.h>
#include<algorithm>
#define eps 1e-9
using namespace std;
struct shape {
	double r, x, y;
	double x1, y1, x2, y2;
	string s;
};

double getdis(double x1, double y1, double x2, double y2) {
	return sqrt((x2 - x1) * (x2 - x1) + (y2 - y1) * (y2 - y1));
}

bool cmp(shape s1, shape s2) {
	if (s1.x1 != s2.x1)return s1.x1 < s2.x1;
	if (s1.y1 != s2.y1)return s1.y1 > s2.y1;
	if (s1.x2 != s2.x2)return s1.x2 > s2.x2;
	if (s1.y2 != s2.y2)return s1.y2 < s2.y2;
}

void cal(double x, double y, double x1, double y1, double x2, double y2, double &mind, double &maxd) {
	double d1, d2, d3, mindis, maxdis;
	if (x1 == x2) {//垂直于x轴的边
		if (y >= min(y1, y2) && y <= max(y1, y2)) {
			d1 = fabs(x1 - x);
			d2 = getdis(x, y, x1, y1);
			d3 = getdis(x, y, x2, y2);
			mindis = min(d1, min(d2, d3));
			maxdis = max(d1, max(d2, d3));
		} else {
			d2 = getdis(x, y, x1, y1);
			d3 = getdis(x, y, x2, y2);
			mindis = min(d2, d3);
			maxdis = max(d2, d3);
		}
	} else {
		if (x >= min(x1, x2) && x <= max(x1, x2)) {
			d1 = fabs(y1 - y);
			d2 = getdis(x, y, x1, y1);
			d3 = getdis(x, y, x2, y2);
			mindis = min(d1, min(d2, d3));
			maxdis = max(d1, max(d2, d3));
		} else {
			d2 = getdis(x, y, x1, y1);
			d3 = getdis(x, y, x2, y2);
			mindis = min(d2, d3);
			maxdis = max(d2, d3);
		}
	}
	mind = min(mind, mindis);
	maxd = max(maxd, maxdis);
}

void solve() {
	string shp;
	shape sp[2];
	for (int i = 0; i < 2; i++) {
		cin >> shp;
		if (shp == "circle") {
			scanf("%lf%lf%lf", &sp[i].r, &sp[i].x, &sp[i].y);
			sp[i].s = "c";
		} else {
			scanf("%lf%lf%lf%lf", &sp[i].x1, &sp[i].y1, &sp[i].x2, &sp[i].y2);
			sp[i].s = "r";
		}
	}
	shape t;
	if (sp[0].s == "r" && sp[1].s == "c") {
		t = sp[0];
		sp[0] = sp[1];
		sp[1] = t;
	}

	shp = sp[0].s + sp[1].s;
	int ans;
	double d;
	if (shp == "cc") {
		d = getdis(sp[0].x, sp[0].y, sp[1].x, sp[1].y);
		if (d <= (sp[0].r + sp[1].r) && d >= (max(sp[0].r, sp[1].r) - min(sp[0].r, sp[1].r))) {
			ans = 1;
		} else {
			ans = 0;
		}
	} else if (shp == "rr") {
		sort(sp, sp + 2, cmp);
		if (sp[1].x1 > sp[0].x1 && sp[1].y1 < sp[0].y1 && sp[1].x2 < sp[0].x2 && sp[1].y2 > sp[0].y2) {
			ans = 0;
		} else {
			if (min(sp[0].x1, sp[0].x2) <= max(sp[1].x1, sp[1].x2) &&
			        min(sp[0].y1, sp[0].y2) <= max(sp[1].y1, sp[1].y2) &&
			        min(sp[1].x1, sp[1].x2) <= max(sp[0].x1, sp[0].x2) &&
			        min(sp[1].y1, sp[1].y2) <= max(sp[0].y1, sp[0].y2)) {
				ans = 1;
			} else {
				ans = 0;
			}
		}
	} else if (shp == "cr") {
		double mind = 5000000;
		double maxd = -5000000;
		cal(sp[0].x, sp[0].y, sp[1].x1, sp[1].y1, sp[1].x2, sp[1].y1, mind, maxd);
		cal(sp[0].x, sp[0].y, sp[1].x1, sp[1].y1, sp[1].x1, sp[1].y2, mind, maxd);
		cal(sp[0].x, sp[0].y, sp[1].x2, sp[1].y2, sp[1].x2, sp[1].y1, mind, maxd);
		cal(sp[0].x, sp[0].y, sp[1].x2, sp[1].y2, sp[1].x1, sp[1].y2, mind, maxd);

		if (maxd < sp[0].r) {
			ans = 0;
		} else if (mind > sp[0].r) {
			ans = 0;
		} else {
			ans = 1;
		}
	}

	if (ans) {
		printf("yes\n");
	} else {
		printf("no\n");
	}

}

int main() {
	int n;
	scanf("%d", &n);
	while (n--) {
		solve();
	}
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值