hdu 4613 Points( KMP 图形学)

来源:互联网 发布:中国为什么封闭网络 编辑:程序博客网 时间:2024/04/28 14:35

http://acm.hdu.edu.cn/showproblem.php?pid=4613


这题感觉有点坑爹,虽然不难推出解法,但实现起来debug到死

取点集的中心,向其他点作向量;

根据各个向量算出向量长度和角坐标,排序;

将需要匹配的点集以同样方法处理,并一致化向量长度;

考虑翻转后的匹配;

重载运算符 kmp匹配

注意点:与中心重合的点必须去掉,否则会干扰翻转后的匹配

#include<cstdio>#include<algorithm>#include<vector>#include<cmath>#include<iostream>#include<queue>#pragma comment(linker, "/STACK:1024000000,1024000000")using namespace std;const int MAXN = 25005;const double eps = 1e-8;const double pi = acos(-1.0);int nx0[MAXN], nx1[MAXN];inline int cmp(const double a, const double b){return (a-b>eps) - (a-b<-eps);}struct vctor{    double x, y;    double agl, dis; /* 0 ~ 2pi */    void build()    {        dis = sqrt(x*x + y*y);        agl = atan2(y, x);        if (agl < 0) agl += 2*pi;    }    bool operator < (const vctor & in) const    {        if (cmp(agl, in.agl) == 0) return dis<in.dis;        return agl < in.agl;    }    bool operator == (const vctor & in) const    {        return cmp(agl, in.agl) == 0 && cmp(dis, in.dis) == 0;    }    void getin() {scanf("%lf%lf", &x, &y);}};struct _data{    int n;    vctor pp[MAXN*2], md0;    double sd;    void getda()    {        scanf("%d", &n);        md0.x = md0.y = 0.0;        for (int i = 0; i< n; ++i)         {            pp[i].getin();            md0.x += pp[i].x;            md0.y += pp[i].y;        }        md0.x /= n; md0.y /= n;    }    void initda(int cs = 1)    {                double dtp;        int itp = 0;        sd = 0.0;        for (int j = 0; j< n; ++j)        {            pp[j].x -= md0.x; pp[j].y -= md0.y;            pp[j].build();            /* important !!!!!*/            if (cmp(pp[j].dis, 0.0))            pp[itp++] = pp[j];        }        n = itp;        sort(pp, pp+n);        dtp = pp[n-1].agl;        for (int i = n-1; i>= 1; pp[i].agl -= pp[(i--)-1].agl);        pp[0].agl += 2*pi-dtp;        if (cs)        for (int i = 0; i< n; ++i) sd += pp[i].dis;    }}da, db, dc;void getpre(int n, int pre[], vctor pp[]){    pre[0] = -1;    for (int i = 1, j=-1; i< n; ++i)    {        while(j > -1 && !(pp[j+1] == pp[i])) j = pre[j];        if (pp[j+1] == pp[i]) ++j;        pre[i] = j;    }}inline void ot(int g){    if (g) puts("Yes");    else puts("No");}int kmp(vctor p[], vctor q[], int n, int m, int next[]){    for (int i = 0, j = 0; i< n; )    {        if (j == -1 || p[i] == q[j])            ++j,++i;        else j = next[j];        if (j == m)            return 1;    }    return 0;}int solve(int s){db.getda();if (db.n != s) return 0;if (s < 3) return 1;    db.initda();    if (db.n != da.n) return 0;    double be = da.sd / db.sd;    for (int i = 0; i< db.n; ++i) db.pp[i].dis *= be;    for (int i = 0; i< db.n; ++i) db.pp[db.n+i] = db.pp[i];    if (kmp(db.pp, da.pp, db.n*2, da.n, nx0) || kmp(db.pp, dc.pp, db.n*2, dc.n, nx1))return 1;elsereturn 0;}int main(){#ifndef ONLINE_JUDGE    freopen("in.txt", "r", stdin);#endif    int t, k, s;    scanf("%d", &t);    while(t--)    {        da.getda();        s = da.n;        dc = da;        for (int i = 0; i< dc.n; ++i) dc.pp[i].x = -dc.pp[i].x;        dc.md0.x = -dc.md0.x;        da.initda();        dc.initda(0);        getpre(da.n, nx0, da.pp);        getpre(dc.n, nx1, dc.pp);        scanf("%d", &k);        while(k--)ot(solve(s));        puts("");    }    return 0;}


0 0
原创粉丝点击