bzoj——1100

大致題意:給一個多邊形,判斷這個多邊形的對稱軸有多少條。

把多邊形的邊和角字符化,然後用馬拉車算法或者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;
}

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章