大致題意:給一個多邊形,判斷這個多邊形的對稱軸有多少條。
把多邊形的邊和角字符化,然後用馬拉車算法或者KMP算法判斷字符串中有多少個迴文。
字符化這個操作是有點秀的。en,有點秀。
最後,代碼:
#include<bits/stdc++.h>
using namespace std;
const int maxn=1e5+100;
long long int s[maxn*4];
long long int x[maxn*2];
int Next[maxn*2]={-1};
int cnt;
int tot;
struct point
{
long long int x,y;
}arr[maxn];
long long int dis(point a,point b)
{
return (a.x-b.x)*(a.x-b.x)+(a.y-b.y)*(a.y-b.y);
}
long long int multiple_cross(point a,point b,point c)
{
return (a.x-c.x)*(b.y-c.y)-(a.y-c.y)*(b.x-c.x);
}
void get_next()
{
int i=0,j=-1;
while(i<=tot)
{
if(j==-1||x[i]==x[j])
{
++i;
++j;
Next[i]=j;
}
else{
j=Next[j];
}
}
}
int Find()
{
int i=0,j=0;
int ans=0;
while(i<cnt)
{
if(j==-1||s[i]==x[j])
{
++i;
++j;
}
else
{
j=Next[j];
}
if(j==tot)
{
++ans;
j=Next[j];
}
}
return ans;
}
int main()
{
int T;
scanf("%d",&T);
while(T--)
{
cnt=0;
tot=0;
int n;
scanf("%d",&n);
for(int i=0;i<n;++i)
{
scanf("%lld %lld",&arr[i].x,&arr[i].y);
}
arr[n]=arr[0];
arr[n+1]=arr[1];
for(int i=0;i<n;++i)
{
s[cnt++]=dis(arr[i+1],arr[i]);
s[cnt++]=multiple_cross(arr[i],arr[i+1],arr[i+2]);
}
for(int i=0;i<cnt;++i)
{
s[i+cnt]=s[i];
}
for(int i=cnt-1;i>=0;--i)
{
x[tot++]=s[i];
}
cnt*=2;
cnt--;
get_next();
cout<<Find()<<endl;
}
return 0;
}