题目链接: http://acm.timus.ru/problem.aspx?space=1&num=1963
题意,顺时针或逆时针给定4个坐标,问对称轴有几条,输出(对称轴数*2)
对于一条对角线,若他是对称轴,必须满足:另外2点关于这条对角线对称 =》 2条对角线互相垂直且 与这条对角线形成的夹角相等
而对于每条边的中点,只需要证明中点相连后与其所在的边垂直即可,垂直且相等就可以证明是对称的
#include <iostream> #include <string> #include <cstring> #include <algorithm> #include <cstdio> #include <cctype> #include <queue> #include <stdlib.h> #include <cstdlib> #include <math.h> #include <set> #include <vector> #define eps 1e-8 #define N 10 using namespace std; struct point { double x,y; }p[N]; bool eq(double a,double b){return (a-b>0?a-b:b-a)<eps;} bool chuizhi(point a,point b,point c,point d){ if(!eq(a.x,b.x) && !eq(c.x,d.x)) return eq(((a.y-b.y)*(c.y-d.y))/((a.x-b.x)*(c.x-d.x)),-1); if(eq(a.x,b.x))return eq(c.y,d.y); if(eq(c.x,d.x))return eq(a.y,b.y); } double dis(point a,point b){ return sqrt((double)((a.x-b.x)*(a.x-b.x)+(a.y-b.y)*(a.y-b.y)));} double du(point a,point b,point c){ double d1=dis(a,b),d2=dis(b,c),d3=dis(c,a); return (d1*d1+d3*d3-d2*d2)/d1*d3; } double k(point a,point b){//斜率 if(a.x==b.x)return 456453454154.154674; return (a.y-b.y)/(a.x-b.x); } bool jiaodu(point a,point b,point c,point d)//a能否作为答案 {//a,b对边 c,d对边 point temp={(c.x+d.x)/2,(c.y+d.y)/2}; if(eq(k(a,b),k(a,temp)))return true; return false; } void zhongdian(){ p[4].x=(p[0].x+p[1].x)/2,p[4].y=(p[0].y+p[1].y)/2; p[5].x=(p[1].x+p[2].x)/2,p[5].y=(p[1].y+p[2].y)/2; p[6].x=(p[2].x+p[3].x)/2,p[6].y=(p[2].y+p[3].y)/2; p[7].x=(p[3].x+p[0].x)/2,p[7].y=(p[0].y+p[3].y)/2; } int main() { while (scanf ("%lf%lf", &p[0].x, &p[0].y) != EOF) { for (int i=1; i<4; ++i) scanf ("%lf%lf", &p[i].x, &p[i].y); int ans=0; zhongdian(); if(chuizhi(p[0],p[2],p[1],p[3])&& jiaodu(p[0],p[2],p[1],p[3]))ans++; if(chuizhi(p[1],p[3],p[0],p[2])&& jiaodu(p[1],p[3],p[0],p[2]))ans++; if(chuizhi(p[4],p[6],p[0],p[1]) && chuizhi(p[4],p[6],p[2],p[3]))ans++; if(chuizhi(p[5],p[7],p[0],p[3]) && chuizhi(p[5],p[7],p[1],p[2]))ans++; printf("%d\n",ans*2); } return 0; } /* 0 0 0 9999 9999 9999 9999 0 0 0 1 2 2 2 2 1 ans: 8 2 */