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; else return 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; }
hdu 4613 Points( KMP 图形学)
最新推荐文章于 2019-08-22 09:44:00 发布