[POI2007] OSI-Axes of Symmetry
Description
Solution
把边和角顺次放入一个数组里,如果一个点为中心的回文串的半径大于\(n\),那就一定是一个对称轴。跑一遍manacher就行。
Code
#include <algorithm>
#include <cmath>
#include <cstdio>
using std::max;
typedef long double ld;
typedef long long ll;
const int N = 4e5 + 10;
const double eps = 1e-8;
struct point {
ll x, y;
point(ll x = 0, ll y = 0) : x(x), y(y) {}
} p[N];
int n, ans[N];
struct state {
double x;
ll md;
state(double x = 0, ll md = 0) : x(x), md(md) {}
bool operator==(const state &a) const {
return md == a.md && fabs(x - a.x) < eps;
}
} f[N];
inline double dis(const point &x, const point &y) {
return sqrt((x.x - y.x) * (x.x - y.x) + (x.y - y.y) * (x.y - y.y));
}
inline double cross(const point &x, const point &y, const point &z) {
return 1.0 * (y.x - x.x) * (z.y - y.y) - 1.0 * (z.x - y.x) * (y.y - x.y);
}
int main() {
#ifdef WYXLOCAL
freopen("tmp.in", "r", stdin);
freopen("tmp.out", "w", stdout);
#endif // WYXLOCAL
int t;
scanf("%d", &t);
while (t--) {
scanf("%d", &n);
for (int i = 1; i <= n; ++i) {
scanf("%lld%lld", &p[i].x, &p[i].y);
}
p[0] = p[n];
p[n + 1] = p[1];
for (int i = 0; i < n; ++i) {
f[i * 2] = state(dis(p[i], p[i + 1]), 1);
f[i * 2 + 1] = state(cross(p[i], p[i + 1], p[i + 2]), 2);
}
for (int i = 0; i < n * 2; ++i) f[n * 2 + i] = f[i];
f[n * 4] = state(0, 0);
int mxr = 0, pos = 0;
for (int i = 0; i < 4 * n; ++i) {
if (i < mxr)
ans[i] = std::min(ans[2 * pos - i], mxr - i + 1);
else
ans[i] = 1;
while (ans[i] <= i && f[i + ans[i]] == f[i - ans[i]]) ans[i]++;
if (i + ans[i] - 1 > mxr) {
mxr = i + ans[i] - 1;
pos = i;
}
}
int cnt = 0;
for (int i = 0; i < 4 * n; ++i)
if (ans[i] > n) cnt++;
printf("%d\n", cnt / 2);
}
return 0;
}
[POI2007] OSI-Axes of Symmetry的更多相关文章
- 开始做POI啦...
库 为了效率搞了这么一个库: 现在版本号1.14(一月十四日更新版本囧..) http://pan.baidu.com/s/1c0SoGfu [source] http://pan.baidu.com ...
- BZOJ 1100: [POI2007]对称轴osi
1100: [POI2007]对称轴osi Time Limit: 10 Sec Memory Limit: 162 MBSubmit: 630 Solved: 243[Submit][Statu ...
- bzoj 1100 [POI2007]对称轴osi manacher
[POI2007]对称轴osi Time Limit: 10 Sec Memory Limit: 162 MBSubmit: 771 Solved: 307[Submit][Status][Dis ...
- 【BZOJ】1100: [POI2007]对称轴osi
题意 给一个\(n(1 \le n \le 100000)\)个点不自交的多边形,求对称轴数目. 分析 将多边形表示成长度和角的形式(用有向面积来表示角也行),然后匹配. 题解 匹配可以用kmp或ma ...
- BZOJ1100 : [POI2007]对称轴osi
将多边形转化为如下的环: 1到2的边,角2,2到3的边,角3,...,n-1到n的边,角n,n到1的边,角1 然后枚举对称轴,如果i是对称轴,那么[i-n,i+n]是一个回文串 用Manacher算法 ...
- 题解-POI2007 OSI-Axes of Symmetry
Problem bzoj1100 题意概要:给定一个简单多边形(不一定凸),求其对称轴数量 数据组数\(\leq 10\),多边形点数\(\leq 10^5\) Solution 这题算是跨界算法的经 ...
- [POI2007]对称轴osi
Description FGD小朋友--一个闻名遐迩的年轻数学家--有一个小MM,yours.FGD小朋友非常喜欢他的MM,所以他很乐意帮助他的MM做数学作业.但是,就像所有科学的容器一样,FGD的大 ...
- bzoj 1100: [POI2007]对称轴osi 思维
特别神的一道题. 有一句话要反复揣摩:题中给的所有点构成一个多边形!! 而且读入还是按照多边形的轮廓读进来的!!! 我们知道,如果对称轴确定的话判定条件是对应角相等且对应边相等. 所以把相邻边夹角和边 ...
- BZOJ 1103: [POI2007]大都市meg [DFS序 树状数组]
1103: [POI2007]大都市meg Time Limit: 10 Sec Memory Limit: 162 MBSubmit: 2221 Solved: 1179[Submit][Sta ...
随机推荐
- Ubuntu禁用root账号,开启Ubuntu密钥登录
新建普通用户 ## 新建普通用户 $ adduser ubuntu $ apt-get install sudo ## 将用户加入sudo组 $ usermod -a -G sudo ubuntu 为 ...
- 数据结构与算法 C++ 视频教程(4 套)百度网盘
为了大二有实力参加算法比赛,大一暑假我选择了留校,提前学习了一下数据结构和算法,这是我找的一些视频资源,分享给大家! 分别是 慕课网 玩转算法与数据结构.慕课网 玩转算法面试.慕课网 玩转数据结构 从 ...
- bootstrap234的ie兼容选择
如果你需要兼容IE8甚至是IE7和IE6,那么只能选择Bootstrap2,虽然它自身在IE6的效果也并不完美.如果需要兼容IE678的话用2.如果需要高版本的浏览器,并且移动端优先的话,那么用boo ...
- java文本文件加密
加密方法是通过输入流对源文件字符逐个读取,对其读取到字符的ascll值进行异或运算,并将其放入新文件中,解密时只要用相同的密钥进行ascll异或运算并向新文件输出即可,即对文件首次用该程序处理为加密, ...
- Python循环引用的解决方案
1.延迟导入:即将 from xxx import yyy 放到函数或类的内部,从而使其作用域变成局部的,但是这样可能会对性能有些影响: 2.将 from xxx import yyy 转换成 imp ...
- linux安装docker和docker compose
运行 sudo -s 切换到root用户. 1.卸载旧版本Docker(如果系统之前没安装过Docker,可以跳过): yum remove docker \ docker-client \ dock ...
- yamlapi接口测试框架
1.思路: yamlapi支持unittest与pytest两种运行模式, yamlapi即为yaml文件+api测试的缩写, 可以看作是一个脚手架工具, 可以快速生成项目的各个目录与文件, 只需维护 ...
- 《操作系统真象还原》BIOS
以下是读本书第二章的收获. 记得我大学学习操作系统的时候会遇到一些奇奇怪怪的问题,因为觉得问题太奇怪了,所以羞于问老师.诸如ROM到底是个什么东西:如果用内存映射的方式访问外部设备,是不是内存条里专门 ...
- BZOJ4566&&lg3181 HAOI找相同字符(广义后缀自动机)
BZOJ4566&&lg3181 HAOI找相同字符(广义后缀自动机) 题面 自己找去 HINT 给定两个文本串,问从两个串中各取一个非空子串,使这俩子串相同,问方案有多少种.我的思路 ...
- 541-反转字符串 II
541-反转字符串 II 给定一个字符串和一个整数 k,你需要对从字符串开头算起的每个 2k 个字符的前k个字符进行反转.如果剩余少于 k 个字符,则将剩余的所有全部反转.如果有小于 2k 但大于或等 ...