HDU 3902 Swordsman(判断任意多边形是否为轴对称图形)
2013-11-04 09:10
525 查看
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=3902
之前做这类题目的时候是先找多边形的重心,因为对称轴一定经过重心,然后再找另外一个点确定对称轴后判断
这次直接给每条线段添加一个中点,然后开始枚举最多n条对称轴,然后判断是否对称
也就是对称轴一定垂直平分其两边的点的连线
判断垂直直接求两向量点积,判断平分,线段中点在对称轴上!
之前做这类题目的时候是先找多边形的重心,因为对称轴一定经过重心,然后再找另外一个点确定对称轴后判断
这次直接给每条线段添加一个中点,然后开始枚举最多n条对称轴,然后判断是否对称
也就是对称轴一定垂直平分其两边的点的连线
判断垂直直接求两向量点积,判断平分,线段中点在对称轴上!
#include <string.h> #include <algorithm> #include <stdio.h> #include <iostream> #include <math.h> using namespace std; #define eps 1e-10 #define maxn 21000 #define mid(a,b) ((a+b)/2) #define zero(x) (fabs(x)<eps?1:0) struct point{ double x,y; }tem[maxn],po[maxn*2],now,then; double cross(point &a,point &b,point &c){ return (b.x-a.x)*(c.y-a.y)-(c.x-a.x)*(b.y-a.y); } double pcross(point &a,point &b,point &c,point &d){ return (a.x-b.x)*(c.x-d.x)+(a.y-b.y)*(c.y-d.y); } bool is_ok(point &a,point &b){ point c; c.x=mid(a.x,b.x) ,c.y=mid(a.y,b.y); return zero(pcross(a,b,now,then)) && zero(cross(now,then,c)); } int n; int main(){ int i,j,k,t; bool flag; while(scanf("%d",&n)!=EOF){ flag=false; for(i=0;i<n;i++)scanf("%lf%lf",&tem[i].x,&tem[i].y); tem =tem[0]; k=0; for(i=1;i<=n;i++){ po[k++]=tem[i-1]; po[k].x=mid(tem[i-1].x,tem[i].x); po[k++].y=mid(tem[i-1].y,tem[i].y); } n=k; t=n/2; for(i=0;i+t<n;i++){ now=po[i],then=po[i+t]; for(j=i+t-1,k=1;j>i;j--,k++){ if(!is_ok(po[j],po[(i+t+k)%n])) break; } if(i==j){ flag=true; break; } } if(flag) printf("YES\n"); else printf("NO\n"); } return 0; }
相关文章推荐
- HDU 1405
- HDU 1297
- hdu 1205
- hdu 2087
- hdu 1016
- HDU 1622 Trees On The Level
- HDU 1063 Exponentiation
- hdu 1202
- HDU 4332(状态压缩dp+矩阵连乘)
- HDU 3065(ac自动机)
- HDU 4714 Tree2cycle
- HDU 4709 Herding
- HDU 4717 The Moving Points
- HDU 4722 Good Numbers
- hdu 1007 Quoit Design
- hdu 1241 Oil Deposits
- 字符串匹配自动机
- HDU 3003
- HDU 3006
- HDU 3008