【BZOJ】1100: [POI2007]对称轴osi

题意

给一个\(n(1 \le n \le 100000)\)个点不自交的多边形,求对称轴数目。

分析

将多边形表示成长度和角的形式(用有向面积来表示角也行),然后匹配。

题解

匹配可以用kmp或manacher。

#include <bits/stdc++.h>
using namespace std;
const int N=400005;
inline int getint() {
    int x=0, f=1, c=getchar();
    for(; c<48||c>57; f=c=='-'?-1:f, c=getchar());
    for(; c>47&&c<58; x=x*10+c-48, c=getchar());
    return x*f;
}
typedef long long ll;
int p[N], X[N], Y[N];
ll a[N], b[N];
inline ll sqr(ll x) {
    return x*x;
}
inline ll cha(ll a, ll b, ll c, ll d) {
    return a*d-b*c;
}
int main() {
    int t=getint();
    while(t--) {
        int n=getint();
        for(int i=1; i<=n; ++i) {
            X[i]=getint();
            Y[i]=getint();
        }
        X[0]=X[n];
        Y[0]=Y[n];
        X[n+1]=X[1];
        Y[n+1]=Y[1];
        for(int i=1; i<=n; ++i) {
            a[i<<1]=sqr(X[i]-X[i+1])+sqr(Y[i]-Y[i+1]);
        }
        for(int i=1; i<=n; ++i) {
            a[(i<<1)-1]=cha(X[i-1]-X[i], Y[i-1]-Y[i], X[i+1]-X[i], Y[i+1]-Y[i]);
        }
        n<<=1;
        for(int i=1; i<=n; ++i) {
            b[n-i+1]=a[i];
            a[i+n]=a[i];
        }
        int ans=0;
        for(int i=2, j=0, lena=n<<1; i<=lena; ++i) {
            for(; j && a[i]!=a[j+1]; j=p[j]);
            p[i]=j+=a[i]==a[j+1];
        }
        for(int i=1, j=0, lena=n<<1; i<=lena; ++i) {
            for(; j && a[i]!=b[j+1]; j=p[j]);
            if((j+=a[i]==b[j+1])==n) {
                ++ans;
                j=p[j];
            }
        }
        printf("%d\n", ans);
    }
    return 0;
}

转载于:https://www.cnblogs.com/iwtwiioi/p/4985632.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值