Links: http://www.lydsy.com/JudgeOnline/problem.php?id=1100
Analysis: Convert the polygon to the following ring:
Angle 0->0 to 1 side length, angle 1->1 to 2 side length->...-> angle n-1->n-1 to 0 edge length. Save it in S, and then copy the S again to the back.
Then the axis of symmetry I is enumerated, nothing but the edge or vertex, if I is the axis of symmetry, then [I-n,i+n] is a palindrome string.
The maximum length (including i) of the longest palindrome extending to the left or right of the symmetric axis is calculated with the Manacher algorithm, when it is greater than N, it is indicated that I is the axis, the corresponding side length and angles are equal, and the symmetric axis counts +1 (PS: Lenovo sliding door).
1#include <cstdio>2#include <algorithm>3#include <cstring>4 using namespacestd;5 6 Const intMAXN =100000+5;7 8 intX[MAXN], Y[MAXN], S[MAXN <<2], P[MAXN <<2];9 TenInlineintDisConst int& A,Const int&b) { One return(X[a]-x[b]) * (X[a]-x[b]) + (Y[a]-y[b]) * (Y[a]-y[b]); A } - -InlineintCrossConst int& A,Const int& B,Const int&c) { the return(X[b]-x[a]) * (Y[c]-y[a])-(x[c]-x[a]) * (Y[b]-Y[a]); - } - - intMain () { + intT; -scanf"%d", &t); + while(t--) { A intN; atscanf"%d", &n); - for(inti =0; I < n; i++) scanf ("%d%d", &x[i], &y[i]); - for(inti =0; I < n; i++) S[i <<1|1] = Dis (i, (i +1) %n); - for(inti =0; I < n; i++) S[i <<1] = Cross (i, (i-1+ N)% n, (i +1) %n); - intAll = N <<1; for(inti =0; I < n; i++) S[all + i] = s[i]; All <<=1; - intAns =0, mx =0, id =0; Memset (P,0,sizeof(P)); in for(inti =0; i < All; i++) { -P[i] = mx > I? Min (P[id *2-i], mx-i):1; to while(I-p[i] >=0&& i + P[i] < all && S[i-p[i]] = = S[i + p[i]]) p[i]++; + if(i + p[i] > mx) {mx = i + p[i]; id =i;} - if(P[i] > N) ans++; the } *printf"%d\n", ans); $ }Panax Notoginseng return 0; -}
BZOJ1100 symmetry OSI (Palindrome string)