记录编号 158144 评测结果 AAAAAAAAAA
题目名称 [USACO Feb12] 对称 最终得分 100
用户昵称 Gravatarcstdio 是否通过 通过
代码语言 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;
}