您的位置:首页 > 其它

【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;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: