【bzoj】1100: [POI2007]对称轴osi
2015-01-10 13:58
302 查看
【算法】
如果多边形关于某个对称轴对称,则从这一点开始的两边的角也是一一对应的(角指的是两条边及夹角),所以用如果将多边形剪成一条线,然后复制一次,在里面找到长度大于等于n的回文串就行了。计算几何和字符串的结合。
【注意】
关于角的相等可以计算出角度和长度,也可以比较 叉积和点积(必须两个) 是否相等。【代码】
写的是Manacher,速度还行,暂列第一页。(忽视代码长度……)/************************************************************** Problem: 1100 User: zhengly123 Language: C++ Result: Accepted Time:1460 ms Memory:15336 kb ****************************************************************/ #include <iostream> #include <stdio.h> #include <stdlib.h> #include <algorithm> #include <math.h> #include <string.h> #define MEM(a) memset(a,0,sizeof(a)) using namespace std; typedef long long LL; const int INF = 999999999; const int N = 400040; const double eps = 1e-8; int G() { int k = 1, tmp = 0; char ch = getchar(); for (; ch > '9' || ch < '0'&&ch != '-'; ch = getchar()); if (ch == '-') k = -1, ch = getchar(); for (; '0' <= ch && ch <= '9'; ch = getchar()) tmp = tmp * 10 + int(ch) - 48; return tmp*k; } int zero(double a) { if (fabs(a) < eps) return 0; else return (a>0) ? 1 : -1; } struct point { double x, y; point(){} point(double a, double b){ x = a; y = b; } friend point operator+(const point&a, const point&b){ return point(a.x + b.x, a.y + b.y); } friend point operator -(const point&a, const point&b){ return point(a.x - b.x, a.y - b.y); } friend point operator *(const double&k, const point&a){ return point(k*a.x, k*a.y); }//数乘 friend point operator /(const point&a, const double&b){ return point(a.x / b, a.y / b); } friend double operator *(const point&a, const point&b){ return a.x*b.x + a.y*b.y; }//点积 friend double operator /(const point&a, const point&b){ return a.x*b.y - a.y*b.x; }//叉积,用^优先级有问题 friend bool operator <(const point&a, const point&b){ return (a.x - b.x < -eps) || (fabs(a.x - b.x) < eps && (a.y - b.y) < -eps); } friend bool operator ==(const point&a, const point&b){ return zero(a.x - b.x) && zero(a.y - b.y); } double dis(){ return (sqrt(x*x + y*y)); } void input(){ /*scanf("%lf%lf",&x,&y)*/x = G(), y = G(); } void output(){ printf("%lf %lf\n", x, y); } }p ; struct angle { double poi, cro; bool operator ==(angle a){ return (zero(poi - a.poi) == 0 && zero(cro - a.cro) == 0); } }s ; int f ; void work() { MEM(f); MEM(s); int i, j, n, id, maxn, nn, ans = 0; scanf("%d", &n); nn = 4 * n - 1; for (i = 1; i <= n; ++i) p[i].input(); p[0] = p , p[n + 1] = p[1], s[0].cro = s[0].poi = INF; for (i = 1; i <= n; ++i) { s[2 * i - 1].poi = (p[i - 1] - p[i]) * (p[i + 1] - p[i]); s[2 * i - 1].cro = (p[i - 1] - p[i]) / (p[i + 1] - p[i]); s[2 * i - 1 + n * 2] = s[2 * i - 1]; } for (f[1] = id = maxn = i = 1; i <= nn; ++i) { if (maxn > i) f[i] = min(f[2 * id - i], maxn - i); else f[i] = 1; for (; s[i + f[i]] == s[i - f[i]]; ++f[i]); if (f[i] + i>maxn) maxn = f[i] + i, id = i; } for (i = n + 1; i <= 3 * n; ++i) if (f[i] >= n - (!(n & 1))) ++ans; printf("%d\n", ans / 2); } int main() { int T; scanf("%d", &T); while (T--) work(); return 0; }
相关文章推荐
- BZOJ_1100_[POI2007]对称轴osi_KMP+计算几何
- 【BZOJ】1100: [POI2007]对称轴osi
- BZOJ1100: [POI2007]对称轴osi
- BZOJ1100 : [POI2007]对称轴osi
- BZOJ 1100: [POI2007]对称轴osi
- 【BZOJ1100】【POI2007】对称轴osi
- BZOJ 1100 [POI2007]对称轴osi
- BZOJ 1100 POI2007 对称轴osi 计算几何+KMP算法
- 1100: [POI2007]对称轴osi
- 【BZOJ】【POI2007】【对称轴osi】【题解】【计算几何】
- bzoj1110 [POI2007]对称轴osi manacher(kmp)
- BZOJ1100: [POI2007]对称轴osi
- [POI2007][对称轴osi][计算几何 + KMP]
- bzoj1100: [POI2007]对称轴osi
- BZOJ1100 [POI2007]砝码Odw 贪心
- bzoj1103 [POI2007]大都市meg
- [莫比乌斯反演] BZOJ1101: [POI2007]Zap
- bzoj1106 [POI2007]立方体大作战tet
- BZOJ1101: [POI2007]Zap 莫比乌斯反演
- 【BZOJ】1098: [POI2007]办公楼biu(补图+bfs+链表)