您的位置:首页 > 其它

[计算几何笔记2]旋转卡壳

2016-02-16 16:22 363 查看
POJ 2187

大概旋转卡壳就是这个意思了。。

int rotating_calipers(Point *ch, int m) /**旋转卡壳模板*/
{
    int q = 1;
    int ans = 0;
    ch[m] = ch[0]; /**凸包边界处理*/
    for(int i = 0; i < m; i++) /**依次用叉积找出凸包每一条边对应的最高点*/
    {/**同底不同高,每次用面积判断高的大小就可以了*/
        while(Cross(ch[i+1]-ch[i], ch[q+1]-ch[i]) > Cross(ch[i+1]-ch[i], ch[q]-ch[i]))
            q = (q+1)%m;
    /**每条底上有两个点,所以要 max 两次*/
        ans = max(ans, max(squarDist(ch[i], ch[q]), squarDist(ch[i+1], ch[q+1])));
    }
    return ans;/**返回的也就是凸包的直径*/
}


另附POJ2187

#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <cmath>

#define maxn 200010
using namespace std;
//-------------------------------------------------------------//
int n;
struct Point{
	int x, y;
	
	bool operator<(const Point& k)const{
		if(x != k.x)return x < k.x;
		return y < k.y;
	}
	
	bool operator==(const Point& k)const{
		return x == k.x && y == k.y;
	}
	
	Point(int x = 0, int y = 0):x(x), y(y){}
	
	void read(){scanf("%d%d", &x, &y);}
	
	void print(){printf("%d %d\n", x, y);}
	
}b[maxn], st[maxn], a[maxn];

Point operator-(const Point& a, const Point& b){
	return Point(a.x - b.x, a.y - b.y);
}

int Cross(const Point& a, const Point& b){
	return a.x * b.y - a.y * b.x;
}

int length(const Point& k){
	return k.x * k.x + k.y * k.y;
}

const double eps = 1e-8;

int Filter(double x){return x > eps ? 1 : (x < -eps ? -1 : 0);}
//-------------------------------------------------------------//

int main(){
	scanf("%d", &n);
	for(int i = 1; i <= n;i ++)
	    b[i].read();
	sort(b+1, b+1+n);
	int top = 0;
	st[++ top] = b[1];
	st[++ top] = b[2];
	for(int i = 3; i <= n; i ++){
		while(top > 1 && Cross(st[top] - st[top - 1], b[i] - st[top - 1]) <= 0)
		    top --;
		st[++ top] = b[i];
	}
	
	for(int i = 1; i <= top; i ++)
		a[i] = st[i];
		
	int cnt = top;
	top = 0;
	
	st[++ top] = b
;
	st[++ top] = b[n - 1];
	for(int i = n - 2; i; i --){
		while(top > 1 && Cross(st[top] - st[top - 1], b[i] - st[top - 1]) <= 0)
		    top --;
		st[++ top] = b[i];
	}
	
	for(int i = 1; i <= top; i ++){
		if(a[cnt] == st[i])continue;
		a[++ cnt] = st[i];
	}
	int ans = 0;
	int r = 2;
	a[cnt+1] = a[2];
	for(int i = 1; i < cnt; i ++){
		while(Cross(a[i+1] - a[i], a[r+1] - a[i]) > Cross(a[i+1] - a[i], a[r] - a[i]))
			r = r % cnt + 1;
		ans = max(length(a[r] - a[i]), ans);
		ans = max(length(a[r+1] - a[i+1]), ans);
	}
	printf("%d\n", ans);
	return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: