A simple polygon is a polygon with non-intersecting edges, also known as Jordan polygon, because the Jordan curve theorem can be used to prove that such polygon can divide the plane into two areas, namely, the area and the area.
When I saw this question, it suddenly hurt. I had a similar problem in both the fjnu competition and the South China Competition in Changsha. The sides of the fjnu competition were parallel to the X and Y axes, you only need to enumerate the symmetry axes in four directions. Changsha is very similar to this question. to enumerate all the symmetry axes, the data is relatively small. The data for this question is large, 20000, And the enumeration symmetry axis is O (n ), determine whether the symmetry axis is O (n), and the complexity is O (n ^ 2). It is very prone to brute-force writing. I read the nlogn method of the question solution and processed it using strings, I found a solution similar to poi2007 on the Internet.
This code is fast and can calculate the number of symmetric axes.
Http://hi.baidu.com/nplusnplusnplu/blog/item/d260baef2e9e9c5879f055cb.html
# Include <iostream> # include <algorithm> # include <cstring> # include <iomanip> # include <cmath> # include <cstdio> using namespace STD; const int maxn = 20010; int n, m, TOT, next [maxn]; int X [maxn], Y [maxn]; long ans; struct point {long ed, AG ;} P [2 * maxn], Q [maxn]; bool operator = (point a, point B) {return. ed = B. ED &. ag = B. AG;} void scanint (Int & X) {char ch; while (CH = getchar (), Ch <'0' | ch> '9 '); X = CH-'0'; while (CH = G Etchar (), ch> = '0' & Ch <= '9') x * = 10, x + = CH-'0';} void findnext () {next [0] =-1; next [1] = 0; For (INT I = 2; I <n; ++ I) {int P = next [I-1]; for (;! (Q [p] = Q [I-1]) & P;) P = next [p]; If (Q [p] = Q [I-1]) next [I] = p + 1; else next [I] = 0 ;}} bool CP (long a, long B, long C, long d) {return a * D-B * C> 0;} int main () {int case; while (~ Scanf ("% d", & N) {for (INT I = 0; I <n; ++ I) {scanf ("% i64d", x + I ); scanf ("% i64d", Y + I);} X [N] = x [0]; y [N] = Y [0]; X [n + 1] = x [1]; y [n + 1] = Y [1]; for (INT I = 0; I <n; ++ I) {long TMP = x [I + 1]-X [I]; TMP * = TMP; P [I]. ed = TMP; TMP = Y [I + 1]-y [I]; TMP * = TMP; P [I]. ED + = TMP; TMP = x [I + 2]-X [I]; TMP * = TMP; P [I]. ag = TMP; TMP = Y [I + 2]-y [I]; TMP * = TMP; P [I]. ag + = TMP; // construct a forward edge, Ed, ag stores the square if (CP (X [I + 2]-X [I], Y [I + 2]-y [I], X [I + 1]-X [I ], Y [I + 1]-y [I]) P [I]. ag =-P [I]. AG;} For (INT I = 2; I <= N; ++ I) {long TMP = x [I]-X [I-1]; TMP * = TMP; Q [n-I]. ed = TMP; TMP = Y [I]-y [I-1]; TMP * = TMP; Q [n-I]. ED + = TMP; TMP = x [I]-X [I-2]; TMP * = TMP; Q [n-I]. ag = TMP; TMP = Y [I]-y [I-2]; TMP * = TMP; Q [n-I]. ag + = TMP; If (! CP (X [I-2]-X [I], Y [I-2]-y [I], X [I-1]-X [I], Y [I-1]-y [I]) Q [n-I]. ag =-Q [n-I]. AG;} long TMP = x [1]-X [0]; TMP * = TMP; Q [N-1]. ed = TMP; TMP = Y [1]-y [0]; TMP * = TMP; Q [N-1]. ED + = TMP; TMP = x [1]-X [N-1]; TMP x = TMP; Q [N-1]. ag = TMP; TMP = Y [1]-y [N-1]; TMP * = TMP; Q [N-1]. ag + = TMP; If (! CP (X [N-1]-X [1], Y [N-1]-y [1], X [0]-X [1], Y [0]-y [1]) Q [N-1]. ag =-Q [N-1]. AG; memcpy (p + N, P, N * sizeof (point); int p = 0; ans = 0; findnext (); For (INT I = 0; I <(n <1)-1; ++ I) {(;! (P [I] = Q [p]) & P;) P = next [p]; If (P [I] = Q [p]) {If (P = N-1) {ans ++; // ans records the number of symmetric axes P = next [p]; If (P [I] = Q [p]) P ++; continue;} p ++ ;}} if (ANS) printf ("Yes \ n"); else printf ("NO \ n ");} return 0 ;}
Self-Organized code: A little slow
# Include <stdio. h> # include <string. h> const int maxn = 20010; int n, m, next [maxn], X [maxn], Y [maxn]; int; long ans; struct point {long ed, AG;} p [2 * maxn], Q [maxn]; bool operator = (point a, point B) {return. ed = B. ED &. ag = B. AG;} void findnext () {next [0] =-1; next [1] = 0; For (INT I = 2; I <n; ++ I) {int P = next [I-1]; (;! (Q [p] = Q [I-1]) & P; P = next [p]); If (Q [p] = Q [I-1]) next [I] = p + 1; else next [I] = 0 ;}} inline bool comp (long a, long B, long C, long d) {return a * D-B * C> 0;} inline long sqr (long x) {return x * X;} void getinf () {for (INT I = 0; I <n; ++ I) // forward {P [I]. ed = sqr (X [I + 1]-X [I]) + sqr (Y [I + 1]-y [I]); P [I]. ag = sqr (X [I + 2]-X [I]) + sqr (Y [I + 2]-y [I]); // printf ("% d \ n", P [I]. ed, P [I]. AG); If (COMP (X [I + 2]-X [I ], Y [I + 2]-y [I], X [I + 1]-X [I], Y [I + 1]-y [I]) P [I]. ag =-P [I]. ag ;}for (INT I = 2; I <= N; ++ I) // returns the reverse {q [n-I]. ed = sqr (X [I]-X [I-1]) + sqr (Y [I]-y [I-1]); Q [n-I]. ag = sqr (X [I]-X [I-2]) + sqr (Y [I]-y [I-2]); If (! Comp (X [I-2]-X [I], Y [I-2]-y [I], X [I-1]-X [I], Y [I-1]-y [I]) Q [n-I]. ag =-Q [n-I]. AG;} Q [N-1]. ed = sqr (X [1]-X [0]) + sqr (Y [1]-y [0]); Q [N-1]. ag = sqr (X [1]-X [N-1]) + sqr (Y [1]-y [N-1]); // printf ("% d \ n", Q [N-1]. ed, Q [N-1]. AG); If (! Comp (X [N-1]-X [1], Y [N-1]-y [1], X [0]-X [1], Y [0]-y [1]) Q [N-1]. ag =-Q [N-1]. AG; memcpy (p + N, P, N * sizeof (point);} int main () {While (~ Scanf ("% d", & N) {for (INT I = 0; I <n; ++ I) {scanf ("% i64d % i64d ", X + I, Y + I);} X [N] = x [0]; y [N] = Y [0]; X [n + 1] = x [1]; y [n + 1] = Y [1]; getinf (); int p = 0; ans = 0; findnext (); For (INT I = 0; I <(n <1)-1; ++ I) {(;! (P [I] = Q [p]) & P; P = next [p]); If (P [I] = Q [p]) {If (P = N-1) {ans ++; P = next [p]; If (P [I] = Q [p]) P ++; continue ;} P ++ ;}} if (ANS) printf ("Yes \ n"); else printf ("NO \ n");} return 0 ;}