zoukankan      html  css  js  c++  java
  • 【POJ】2187 Beauty Contest(旋转卡壳)

    http://poj.org/problem?id=2187

    显然直径在凸包上(黑书上有证明)。(然后这题让我发现我之前好几次凸包的排序都错了QAQ只排序了x轴。。。。。没有排序y轴。。

    然后本题数据水,暴力也能过。。。

    (之前一直以为距离是单增的,其实并不是,应该是三角形面积单增...)

    考虑旋转卡壳

    一篇好的文章:http://www.cnblogs.com/Booble/archive/2011/04/03/2004865.html

    首先对踵点就是两条平行线夹紧凸包的两个点(或者3个点或4个点,平行线过两个点情况,凸包去掉三点共线)时的点对,可以证明对踵点对最多只有3N/2个

    首先卡住一点-两点(即边)可以等效于卡主一点-一点(前边的点),所以我们只需要找边的前一个点的对踵点即可。

    性质1:对踵点对之间的距离最大

    证明:黑书上有...

    因此我们只需要枚举每条边,找出对应的对踵点(用叉积求面积来找,这条边与其它点的面积是单峰的,然后往后递推决策是单调不降的)

    性质2:当枚举边按序枚举时,对踵点的位置单增

    证明:不会QAQ似乎黑书上也有?

    这就提供了一个很好的性质,即我们枚举边时维护一下对踵点的位置即可,那么查找对踵点的复杂度均摊$O(n)$

    性质3:每个点的对踵点不一定只有1个

    证明:显然吧。。。

    由于性质3的存在,我们考虑是否我们枚举边找到第一个对踵点就更新的算法会出现问题?

    答案是不会。

    因为我们枚举边时已经遍历了所有点,因此遗漏的对踵点的距离总是会计算到

    #include <cstdio>
    #include <cstring>
    #include <cmath>
    #include <string>
    #include <iostream>
    #include <algorithm>
    #include <queue>
    #include <set>
    #include <vector>
    #include <map>
    using namespace std;
    typedef long long ll;
    #define pii pair<int, int>
    #define mkpii make_pair<int, int>
    #define pdi pair<double, int>
    #define mkpdi make_pair<double, int>
    #define pli pair<ll, int>
    #define mkpli make_pair<ll, int>
    #define rep(i, n) for(int i=0; i<(n); ++i)
    #define for1(i,a,n) for(int i=(a);i<=(n);++i)
    #define for2(i,a,n) for(int i=(a);i<(n);++i)
    #define for3(i,a,n) for(int i=(a);i>=(n);--i)
    #define for4(i,a,n) for(int i=(a);i>(n);--i)
    #define CC(i,a) memset(i,a,sizeof(i))
    #define read(a) a=getint()
    #define print(a) printf("%d", a)
    #define dbg(x) cout << (#x) << " = " << (x) << endl
    #define error(x) (!(x)?puts("error"):0)
    #define printarr2(a, b, c) for1(_, 1, b) { for1(__, 1, c) cout << a[_][__]; cout << endl; }
    #define printarr1(a, b) for1(_, 1, b) cout << a[_] << '	'; cout << endl
    inline const int getint() { int r=0, k=1; char c=getchar(); for(; c<'0'||c>'9'; c=getchar()) if(c=='-') k=-1; for(; c>='0'&&c<='9'; c=getchar()) r=r*10+c-'0'; return k*r; }
    inline const int max(const int &a, const int &b) { return a>b?a:b; }
    inline const int min(const int &a, const int &b) { return a<b?a:b; }
    
    const int N=50005;
    struct dat { int x, y; }a[N], b[N];
    
    int cha(const dat &a, const dat &b, const dat &c) {
    	static int x1, x2, y1, y2;
    	x1=a.x-c.x, x2=b.x-c.x, y1=a.y-c.y, y2=b.y-c.y;
    	return x1*y2-x2*y1;
    }
    int n;
    bool cmp(const dat &a, const dat &b) { return a.x==b.x?a.y<b.y:a.x<b.x; }
    void tu() {
    	sort(a+1, a+1+n, cmp);
    	int top=0;
    	for1(i, 1, n) {
    		while(top>1 && cha(a[i], b[top], b[top-1])>=0) --top;
    		b[++top]=a[i];
    	}
    	int k=top;
    	for3(i, n-1, 1) {
    		while(top>k && cha(a[i], b[top], b[top-1])>=0) --top;
    		b[++top]=a[i];
    	}
    	if(n>1) --top;
    	n=top;
    }
    int sqr(const int x) { return x*x; }
    int dis(const dat &a, const dat &b) { return sqr(a.x-b.x)+sqr(a.y-b.y); }
    
    int main() {
    	read(n);
    	for1(i, 1, n) read(a[i].x), read(a[i].y);
    	tu();
    	int ans=0;
    	b[n+1]=b[1];
    	int j=2;
    	for1(i, 1, n) {
    		while(cha(b[i+1], b[j+1], b[i])>cha(b[i+1], b[j], b[i])) j=j%n+1;
    		ans=max(ans, dis(b[i], b[j]));
    	}
    	printf("%d
    ", ans);
    	return 0;
    }
    

      


    Description

    Bessie, Farmer John's prize cow, has just won first place in a bovine beauty contest, earning the title 'Miss Cow World'. As a result, Bessie will make a tour of N (2 <= N <= 50,000) farms around the world in order to spread goodwill between farmers and their cows. For simplicity, the world will be represented as a two-dimensional plane, where each farm is located at a pair of integer coordinates (x,y), each having a value in the range -10,000 ... 10,000. No two farms share the same pair of coordinates. 

    Even though Bessie travels directly in a straight line between pairs of farms, the distance between some farms can be quite large, so she wants to bring a suitcase full of hay with her so she has enough food to eat on each leg of her journey. Since Bessie refills her suitcase at every farm she visits, she wants to determine the maximum possible distance she might need to travel so she knows the size of suitcase she must bring.Help Bessie by computing the maximum distance among all pairs of farms. 

    Input

    * Line 1: A single integer, N 

    * Lines 2..N+1: Two space-separated integers x and y specifying coordinate of each farm 

    Output

    * Line 1: A single integer that is the squared distance between the pair of farms that are farthest apart from each other. 

    Sample Input

    4
    0 0
    0 1
    1 1
    1 0
    

    Sample Output

    2
    

    Hint

    Farm 1 (0, 0) and farm 3 (1, 1) have the longest distance (square root of 2) 

    Source

  • 相关阅读:
    【ARM-Linux开发】Linux下更改目录下所有文件的所有者及其权限
    【ARM-Linux开发】Linux下更改目录下所有文件的所有者及其权限
    # 【ARM-Linux开发】在Win7的电脑上直接运行安装Ubuntu14.04发生的问题 标签(空格分隔): 【Linux开发】 --- > 一段时间以来,一直是在Windows上安装虚拟机
    # 【ARM-Linux开发】在Win7的电脑上直接运行安装Ubuntu14.04发生的问题 标签(空格分隔): 【Linux开发】 --- > 一段时间以来,一直是在Windows上安装虚拟机
    【ARM-Linux开发】wubi.exe安装Ubuntu14.04出现为/检查磁盘时发生严重错误的解决方法
    【ARM-Linux开发】wubi.exe安装Ubuntu14.04出现为/检查磁盘时发生严重错误的解决方法
    【VS开发】winsock 错误多 windows.h和winsock2.h的顺序
    【VS开发】winsock 错误多 windows.h和winsock2.h的顺序
    【FFMPEG】VS2013编译ffmpeg
    【FFMPEG】VS2013编译ffmpeg
  • 原文地址:https://www.cnblogs.com/iwtwiioi/p/4184387.html
Copyright © 2011-2022 走看看