码迷,mamicode.com
首页 > 其他好文 > 详细

bzoj 1100

时间:2018-06-23 19:20:19      阅读:167      评论:0      收藏:0      [点我收藏+]

标签:rev   i++   space   col   can   字符   get   mod   turn   

思路:好脑洞啊。。。 把边和角转化为字符串,然后用反串跑kmp。。。

#include<bits/stdc++.h>
#define LL long long
#define fi first
#define se second
#define mk make_pair
#define pii pair<int, int>

using namespace std;

const int N = 1e5 + 7;
const int M = 1e6 + 7;
const int inf = 0x3f3f3f3f;
const LL INF = 0x3f3f3f3f3f3f3f3f;
const int mod = 1e9 +7;

int n, m;
LL a[N << 2], b[N << 2];
int nx[N << 2];
struct Point {
    LL x, y;
    Point(LL x = 0, LL y = 0) {
        this->x = x;
        this->y = y;
    }

    Point operator - (const Point &rhs) const {
        return Point(x - rhs.x, y - rhs.y);
    }
} p[N];


typedef Point Vector;
LL dis(const Point &a, const Point &b) {
    return (a.x - b.x) * (a.x - b.x) + (a.y - b.y) * (a.y - b.y);
}

LL cross(Vector a, Vector b) {
    return a.x * b.y - a.y * b.x;
}

void getNext() {
    int k = 0;
    for(int i = 1; i < m; i++) {
        while(k > 0 && b[k] != b[i]) k = nx[k - 1];
        if(b[k] == b[i]) k++;
        nx[i] = k;
    }
}

int kmp() {
    int k = 0, ans = 0;
    for(int i = 0; i < n; i++) {
        while(k > 0 && b[k] != a[i]) k = nx[k - 1];
        if(b[k] == a[i]) k++;
        if(k == m) {
            ans++;
            k = nx[k - 1];
        }
    }
    return ans;
}

int main(){
    int T; scanf("%d", &T);
    while(T--) {
        scanf("%d", &n);
        for(int i = 0; i < n; i++) {
            scanf("%lld%lld", &p[i].x, &p[i].y);
        }

        for(int i = 0; i < n; i++) {
            Vector v1 = p[(i + 1) % n] - p[i];
            Vector v2 = p[(i - 1 + n) % n] - p[i];
            a[i << 1] = cross(v1, v2);
        }

        for(int i = 0; i < n; i++) {
            a[i << 1 | 1] = dis(p[i], p[(i + 1) % n]);
        }

        for(int i = 2 * n; i < 4 * n; i++) {
            a[i] = a[i - 2 * n];
        }

        m = 2 * n;
        n = 4 * n;

        for(int i = 0; i < m; i++) {
            b[i] = a[i];
        }
        reverse(b, b + m);

        getNext();
        printf("%d\n", kmp());
    }
    return 0;
}

/*
*/

 

bzoj 1100

标签:rev   i++   space   col   can   字符   get   mod   turn   

原文地址:https://www.cnblogs.com/CJLHY/p/9217503.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!