记录编号 |
158144 |
评测结果 |
AAAAAAAAAA |
题目名称 |
[USACO Feb12] 对称 |
最终得分 |
100 |
用户昵称 |
cstdio |
是否通过 |
通过 |
代码语言 |
C++ |
运行时间 |
0.008 s |
提交时间 |
2015-04-12 21:25:23 |
内存使用 |
0.32 MiB |
显示代码纯文本
#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cstring>
#include<set>
using namespace std;
const int SIZEN=1010;
int gcd(int a,int b){return !b?a:gcd(b,a%b);}
class Point{
public:
int x,y;
Point(int x_=0,int y_=0){x=x_,y=y_;}
};
Point normalize(Point a){
int g=gcd(a.x,a.y);
a.x/=g,a.y/=g;
return a;
}
bool operator < (const Point &a,const Point &b){
return a.x==b.x?a.y<b.y:a.x<b.x;
}
Point operator + (const Point &a,const Point &b){
return Point(a.x+b.x,a.y+b.y);
}
Point operator - (const Point &a,const Point &b){
return Point(a.x-b.x,a.y-b.y);
}
Point operator * (int a,const Point &b){
return Point(a*b.x,a*b.y);
}
int operator * (const Point &a,const Point &b){
return a.x*b.x+a.y*b.y;
}
int lensqr(const Point &a){
return a*a;
}
Point vertical(const Point &a){//逆时针旋转90度
return Point(-a.y,a.x);
}
class Line{
public:
Point pos;
Point dir;//必须是normalize过的
Line(){}
Line(const Point &a,const Point &b){
pos=a;
dir=normalize(b-a);
}
};
bool midper(const Point &a,const Point &b,Line &L){//ab中垂线为L,若不合法返回false
L.pos=a+b;
if(L.pos.x%2||L.pos.y%2) return false;
L.pos.x/=2,L.pos.y/=2;
L.dir=normalize(vertical(b-a));
return true;
}
bool calc_sym(const Line &L,const Point &P,Point &P1){//对称点是否为整点,对称点存放在P1中
//大致是先算出来P到L的垂足的参数
int a=L.dir*L.dir,b=(P-L.pos)*L.dir;
if(b%a) return false;
int t=b/a;
P1=2*(L.pos+t*L.dir)-P;
return true;
}
int N;
Point P[SIZEN];
set<Point> PS;
bool check(Line L){
Point p1;
for(int i=1;i<=N;i++){
if(!calc_sym(L,P[i],p1)) return false;
if(!PS.count(p1)) return false;
}
return true;
}
void work(void){
int ans=0;
//情况1:P1在对称轴外
Line L;
for(int i=2;i<=N;i++){
if(midper(P[1],P[i],L)){
if(check(L)) ans++;
}
}
//情况2:P1在对称轴上,P2在对称轴外
for(int i=3;i<=N;i++){
if(midper(P[2],P[i],L)&&lensqr(P[i]-P[1])==lensqr(P[2]-P[1])){
if(check(L)) ans++;
}
}
//情况3:P1,P2均在对称轴上
if(check(Line(P[1],P[2]))) ans++;
printf("%d\n",ans);
}
void read(void){
scanf("%d",&N);
for(int i=1;i<=N;i++){
scanf("%d%d",&P[i].x,&P[i].y);
P[i]=2*P[i];
PS.insert(P[i]);
}
}
int main(){
freopen("symmetry.in","r",stdin);
freopen("symmetry.out","w",stdout);
read();
work();
return 0;
}