poj 2187
来源:互联网 发布:黑社会2 知乎 编辑:程序博客网 时间:2024/05/28 01:35
题目概述
平面直角坐标系中给定N个相互独立的点的坐标x,y,求最远两点间距离的平方
时限
3000ms/9000ms
输入
第一行正整数N,其后N行,每行两个整数x,y,输入到EOF为止
限制
2<=N<=50000;-10000<=x,y<=10000
输出
每行一个数,为所求距离的平方
样例输入
4
0 0
0 1
1 1
1 0
8
5 15
15 10
0 0
10 0
-5 10
0 10
5 5
-1 6
2
0 0
0 1
4
0 0
0 1
0 2
0 3
样例输出
2
400
1
9
讨论
计算几何,旋转卡(qia3)壳(qiao4),当然也得求凸包,题目已经直接抽象好了,主要思想就是求旋转卡壳,要么理解思想,要么背模版,好在这部分的资料相当好找,额也就不赘述了
实现方面,基本无大坑,只是注意旋转卡壳的要可靠,最后需要用两个点比较取最远然后再和以前的最远比较,这点第二组样例可以测试,其次就是点数过少(样例三)和全部共线(样例四)的情况,不过由于andrew凸包的鲁棒性,这两条不单独考虑也不会出问题
然而额由于困成树懒,写旋转卡壳时忘了是在栈中,又样例数据凑巧,故连WA多次
题解代码测试了两种做法,andrew凸包+枚举=线性对数级+平方级,andrew凸包+旋转卡壳=线性对数级+线性级,不过由于向量积常数过大,前者仅测一次便明显快于后者,哪怕用内联,max用宏函数,也一样较慢(额交了近10次都比不上)
题解状态
枚举:564K,79MS,C++,1239B
旋转卡壳:564K,94MS,C++,1408B
题解代码
枚举
#include<cstdio>#include<cstring>#include<algorithm>#include<cmath>using namespace std;#define INF 0x3f3f3f3f#define MAXN 50003#define memset0(a) memset(a,0,sizeof(a))#define EPS 1e-8struct Pt//point 点的结构{ int x, y; bool operator<(const Pt &b)const { return y != b.y ? y < b.y : x < b.x; }}pts[MAXN];int N;//点总数int stk[MAXN], top;//stack 数组模拟栈及其栈顶int xp(Pt &a, Pt &b, Pt &c)//向量积{ return (a.x - b.x)*(c.y - b.y) - (a.y - b.y)*(c.x - b.x);}int dis2(Pt &a, Pt &b)//两点间距离的平方{ return (a.x - b.x)*(a.x - b.x) + (a.y - b.y)*(a.y - b.y);}int fun(){ for (int p = 0; p < N; p++) scanf("%d%d", &pts[p].x, &pts[p].y);//input sort(pts, pts + N);//排序 下面是andrew凸包 还没忘怎么写 for (int p = 0; p < N; p++) { while (top > 1 && xp(pts[p], pts[stk[top - 2]], pts[stk[top - 1]]) >= 0) top--; stk[top++] = p; } int stklen = top; for (int p = N - 2; p >= 0; p--) { while (top > stklen&&xp(pts[p], pts[stk[top - 2]], pts[stk[top - 1]]) >= 0) top--; stk[top++] = p; } top--;//去除多算了一次的凸包起点 int most = -INF;//下面枚举找出最远点 只有两处常数 for (int p = 0; p < top; p++) for (int i = p + 1; i < top; i++) most = max(most, dis2(pts[stk[p]], pts[stk[i]])); return most;}int main(void){ //freopen("vs_cin.txt", "r", stdin); //freopen("vs_cout.txt", "w", stdout); while (~scanf("%d", &N)) {//input printf("%d\n", fun());//output top = 0;//清零栈 }}
旋转卡壳:
#include<cstdio>#include<cstring>#include<algorithm>#include<cmath>using namespace std;#define INF 0x3f3f3f3f#define MAXN 50003#define memset0(a) memset(a,0,sizeof(a))#define EPS 1e-8struct Pt//point 点的结构{ int x, y; bool operator<(const Pt &b)const { return y != b.y ? y < b.y : x < b.x; }}pts[MAXN];int N;//点总数int stk[MAXN], top;//stack 数组模拟栈及其栈顶inline int xp(Pt &a, Pt &b, Pt &c)//向量积 内联的{ return (a.x - b.x)*(c.y - b.y) - (a.y - b.y)*(c.x - b.x);}inline int dis2(Pt &a, Pt &b)//两点间距离的平方 也是内联{ return (a.x - b.x)*(a.x - b.x) + (a.y - b.y)*(a.y - b.y);}int fun(){ for (int p = 0; p < N; p++) scanf("%d%d", &pts[p].x, &pts[p].y);//input sort(pts, pts + N);//排序 下面是andrew凸包 for (int p = 0; p < N; p++) { while (top > 1 && xp(pts[p], pts[stk[top - 2]], pts[stk[top - 1]]) >= 0) top--; stk[top++] = p; } int stklen = top; for (int p = N - 2; p >= 0; p--) { while (top > stklen&&xp(pts[p], pts[stk[top - 2]], pts[stk[top - 1]]) >= 0) top--; stk[top++] = p; } top--;//去除算了两次的凸包起点 下面是旋转卡壳 int most = 0, app = 2;//most 最远两点距离平方 antipodal_point 对踵点 肯定不会是前两个点 for (int p = 0; p < top; p++) {//枚举栈中的点 是栈 不是所有点 while (xp(pts[stk[p + 1]], pts[stk[p]], pts[stk[app + 1]])>xp(pts[stk[p + 1]], pts[stk[p]], pts[stk[app]]))//对于枚举的点 其对踵点是其余点中到枚举的点距离最远的点 由于凸包是逆时针构成 两点距离到极大值时便成对踵点 这里不直接求距离 而是利用三角形(有向)面积比较 app = (app + 1) % top; most = max(most, max(dis2(pts[stk[p]], pts[stk[app]]), dis2(pts[stk[p + 1]], pts[stk[app]])));//由于每次实际上是枚举凸包上相邻两个点所成的线 因而需要判断到底线上哪个点更远一点 } return most;}int main(void){ //freopen("vs_cin.txt", "r", stdin); //freopen("vs_cout.txt", "w", stdout); while (~scanf("%d", &N)) {//input printf("%d\n", fun());//output top = 0;//清零栈 }}
EOF
0 0
- poj 2187
- poj 2187
- poj 2187
- poj 2187
- poj 2187
- poj 2187
- POJ 2187
- poj 旋转卡壳三题 poj 2187 poj 2079
- POJ 2187 Beauty Contest
- POJ-2187-凸包
- poj 2187 Beauty Contest
- POJ 2187 Beauty Contest
- poj 2187 Beauty Contest
- POJ 2187 Beauty Contest
- POJ 2187 Beauty Contest
- poj 2187 Beauty Contest
- POJ 2187 Beauty Contest
- POJ 2187 Beauty Conteset
- 来来来,一步一步带你使用Git和GitHub(详细讲解.gitignore)
- 使用pyinstaller打包Python3.5+PyQt5.6项目生成exe文件
- 京城游戏人-Day11: Unity 中实现 IAP 内购(内付费)
- Tomcat8.x Request、Response创建的地方
- 京城游戏人-Day12: Unity 中 UI 随屏幕大小等比缩放
- poj 2187
- 同余方程组求解
- 用C语言改写C++的类
- 51Nod-1100-斜率最大
- Ubuntu14.10环境下MySQL5.6.23源码安装MySQL安装小结
- 四大CPU体系结构ARM、X86/Atom、MIPS、PowerPC
- Android studio gradle配置
- [DP]Builder设计模式
- 树莓派 Learning 003 --- GPIO 000 --- GPIO引脚图