http://oj.cs203.net/problem.php?id=1269
【题解】:
给定一个在笛卡尔坐标系中的无自交多边形,判断是否轴对称。
若顶点数是奇数,则对称轴一定经过一顶点和其对边的中点。
若定点数是偶数,则对称轴可能经过2个相对的顶点,也可能经过2个对边的中点。
分好类就不难做了。
#include <stdio.h>
#include <string.h>
#include <algorithm>
using namespace std;
#define p2(x) ((x)*(x))
#define MAXN 10001
int T, n;
bool f[13];
struct POINT{
int x, y;
}p[13], m, mm;
int ping(POINT &a, POINT &b){
return 0==(a.x*b.y - a.y*b.x);
}
int deng(POINT &m, POINT &a, POINT &b){
return p2(m.x-a.x)+p2(m.y-a.y) == p2(m.x-b.x)+p2(m.y-b.y);
}
int bili(POINT &mi, POINT &mj, POINT &i, POINT &j){
return abs( (i.x-j.x)*(mi.y-mj.y) ) == abs( (i.y-j.y)*(mi.x-mj.x) );
}
int main(){
while( EOF != scanf("%d", &T) ){
while( T-- && EOF != scanf("%d", &n) ){
for(int i=0,x,y; i<n; i++)
scanf("%d%d", &p[i].x, &p[i].y);
int ans = 0;
if( n&1 ){
for(int m=0, dis=n-1; m<n; m++){
memset(f, 0, sizeof(f));
for(int i=0, j; i<n; i++){
if( m==i || f[i] ) continue;
for(j=i+1; j<n; j++){
if( m==j || f[j] ) continue;
if( deng(p[m], p[i], p[j]) ){
f[i]=f[j]=1, dis -= 2;
if( !dis ) ans = 1, m=i=j=100;
j = 100;
}
}
if( j==n ) i = 100;
}
}
}
else{
for(int mi=0; mi<n; mi++){
for(int mj=mi+1, dis=n; mj<n; mj++){
m.x = p[mi].x-p[mj].x, m.y = p[mi].y-p[mj].y;
memset(f, 0, sizeof(f));
f[mi] = f[mj] = 1;
for(int i=0, j; i<n; i++){
if( mi==i || mj==i || f[i] ) continue;
for(j=i+1; j<n; j++){
if( mi==j || mj==j || f[j] ) continue;
mm.x = p[i].x-p[j].x, mm.y = p[i].y-p[j].y;
if( ping(m, mm) && bili(p[mi], p[mj], p[i], p[j])){
f[i]=f[j]=1, dis -= 2;
if( !dis ) ans = 1, mi=mj=i=j=100;
j = 100;
}
}
if( j==n ) i = 100;
}
}
}
}
printf("The soap %s belong to the bear !\n", ans?"may":"does not");
}
}
return 0;
}