FZU - 2035 Axial symmetry(几何+暴力)

题意:顺时针或逆时针给定一些点,判断该n边形是否对称。

思路:由于点是顺逆时或逆时针针输入,所以可以把每个点和每条边中点按顺序保存,
然后对称轴必然由i,i + n组成,枚举对称轴
对称轴有4种情况,
(1)对称轴垂直于x轴,要判断,每组对称点的x值是否相等,以及他们的中点是否等于对称轴。
(2)对称轴垂直于y轴,要判断,每组对称点的y值是否相等,以及他们的中点是否等于对称轴。
(3)对称轴的斜率为1,要判断,每组对称点的斜率是否为-1。

(4)对称轴的斜率为-1,要判断,每组对称点的斜率是否为1。

#include <cstdio>
#include <cstring>
#include <cmath>
using namespace std;
const int N = 1005;

struct Node {
	double x,y;
	Node() {}
	Node(double _x,double _y) {
		x = _x;
		y = _y;
	}
}node[N], p[2*N];

int n;
int main() {
	int t,cas = 1;
	scanf("%d",&t);
	while(t--) {
		scanf("%d",&n);
		for(int i = 0; i < n; i++) {
			scanf("%lf%lf",&node[i].x,&node[i].y);
		}
		node[n] = node[0];

		int tot = 0;

		p[tot++] = node[0];
		for(int i = 0; i <= n; i++) {
			p[tot++] = Node((node[i].x + node[i+1].x) / 2, (node[i].y + node[i+1].y) / 2);
			p[tot++] = node[i+1];
		}
		int a,b;
		double k1, k2, c;
		bool ok, flag = false;
		for(int i = 0; i < n; i++) { //枚举对称轴
			ok = true;
			if( p[i].x == p[i+n].x ) { //如果分母为0,则对称轴垂直于x轴
				for(int j = 1; j < n; j++) { //对称点 i+j 和 i-j + 2n
					a = (i+j);
					b = (i-j+2*n);
					if( (p[a].x + p[b].x)/2 != p[i].x || (p[a].y != p[b].y)) {
						ok = false;
						break;
					}
				}
			}else if( p[i].y == p[i+n].y) { //如果分子为0,则对称轴垂直于y轴
				for(int j = 1; j < n; j++) {
					a = (i+j);
					b = (i-j+2*n);
					if( (p[a].y + p[b].y)/2 != p[i].y || (p[a].x != p[b].x)) {
						ok = false;
						break;
					}
				}
			}else if(p[i].y - p[i+n].y == p[i].x - p[i+n].x) { //斜率存在,则对称轴一定为45度
				for(int j = 1; j < n; j++) {
					a = (i+j);
					b = (i-j+2*n);
					if(p[a].y - p[b].y != p[b].x - p[a].x) {
						ok = false;
						break;
					}
				}
			}else if(p[i].y - p[i+n].y == p[i+n].x - p[i].x) {
				for(int j = 1; j < n; j++) {
					a = (i+j);
					b = (i-j+2*n);
					if(p[a].y - p[b].y != p[a].x - p[b].x) {
						ok = false;
						break;
					}
				}
			}else {
				continue;
			}
			if(ok) {
				flag = true;
				break;
			}
		}
		printf("Case %d: ",cas++);
		if(flag) {
			printf("YES\n");
		}else {
			printf("NO\n");
		}
	}
	return 0;
}


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值