1203 - Guarding Bananas
Time Limit: 3 second(s) Memory Limit: 32 MB

Once there was a lazy monkey in a forest. But he loved banana too much. One day there was a storm in the jungle and all the bananas fell from the trees. The monkey didn't want to lose any of the bananas. So, he wanted to find a banana such that he can eat that and he can also look after the other bananas. As he was lazy, he didn't want to move his eyes too wide. So, you have to help him finding the banana from where he can look after all the bananas but the degree of rotating his eyes is as small as possible. You can assume that the position of the bananas can be modeled as 2D points.

Here a banana is shown, from where the monkey can look after all the bananas with minimum eye rotation.

Input

Input starts with an integer T (≤ 13), denoting the number of test cases.

Each case starts with a line containing an integer n (1 ≤ n ≤ 105) denoting the number of bananas. Each of the next n lines contains two integers x y (-109 ≤ x, y ≤ 109) denoting the co-ordinate of a banana. There can me more than one bananas in the same co-ordinate.

Output

For each case, print the case number and the minimum angle in degrees. Errors less than 10-6 will be ignored.

Sample Input

Output for Sample Input

2

1

4 4

4

0 0

10 0

10 10

2 1

Case 1: 0

Case 2: 45.0000000

Note

Dataset is huge. Use faster I/O methods.

  • 题意:在所有给定的香蕉中找到一个香蕉,使得从这个香蕉看向其他香蕉的角度尽可能小的同时看到的香蕉数目尽可能多。
  • 由于香蕉可以化为半径忽略不计的二维平面上的点,所以可以想到,站在这些点的凸包的顶点处看过去的角度小并且看到的点更多,否则,总可以向这些定顶点处移动,使得看到的点更多或者角度更小。
  • 所以这道题就是求其凸包,然后找到里面最小的那个内角。
  •  #include<iostream>
    #include<algorithm>
    #include<cmath>
    #include<cstdio>
    #include<cstring>
    using namespace std;
    const int maxn = 1e5 + ;
    const double pi = acos(-1.0);
    const double eps = 1e-;
    int sgn(double x) {
    if (fabs(x) < eps)return ;
    if (x < )return -;
    else return ;
    }
    typedef struct point {
    double x, y;
    point() { }
    point(double a, double b) {
    x = a;
    y = b;
    }
    point operator -(const point &b) const {
    return point(x - b.x, y - b.y);
    }
    double operator *(const point &b)const {
    return x*b.x + y*b.y;
    }
    double operator ^(const point &b)const { //叉乘
    return x*b.y - y*b.x;
    }
    bool operator <(point b)const {
    return sgn(x - b.x) == ? sgn(y - b.y)< : x<b.x;
    }
    //返回pa,pb的夹角,该点看a,b的夹角,弧度制
    //弧度=度×π/180°
    //度=弧度×180°/π
    double rad(point a, point b) {
    point p = *this;
    return fabs(atan2(fabs((a - p) ^ (b - p)), (a - p)*(b - p)));
    }
    }point;
    point p[maxn];
    int n = , res[maxn];
    int top;//top模拟栈顶
    bool multi(point p1, point p2, point p0) { //判断p1p0和p2p0的关系,<0,p1p0在p2p0的逆时针方向,>0,p1p0在p2p0的顺时针方向
    return (p1.x - p0.x)*(p2.y - p0.y) >= (p2.x - p0.x)*(p1.y - p0.y);
    }
    double Graham() {
    int i, len;//top模拟栈顶
    sort(p, p + n);
    top = ;
    //少于3个点也就没有办法形成凸包
    if (n == )return ; res[] = ;
    if (n == )return ; res[] = ;
    if (n == )return ; res[] = ;
    for (i = ; i < n; i++) {
    while (top&&multi(p[i], p[res[top]], p[res[top - ]])) //如果当前这个点和栈顶两个点构成折线右拐了,就回溯到上一个点
    top--; //弹出栈顶
    res[++top] = i; //否则将这个点入栈
    }
    len = top;
    res[++top] = n - ;
    for (i = n - ; i >= ; i--) {
    while (top != len&&multi(p[i], p[res[top]], p[res[top - ]]))
    top--;
    res[++top] = i;
    }
    double ans =0x3f3f3f;
    res[top] = res[],res[top + ] = res[];
    for (int i = ; i <= top; i++) {
    ans = min(ans, p[res[i]].rad(p[res[i + ]], p[res[i - ]]));
    }
    return ans / pi * ;
    }
    inline int read()
    {
    int x = , f = ; char ch = getchar();
    while (ch<'' || ch>'') { if (ch == '-')f = -; ch = getchar(); }
    while (ch >= ''&&ch <= '') { x = x * + ch - ''; ch = getchar(); }
    return x*f;
    }
    int main(void) {
    int t;
    t = read();
    for (int cnt = ; cnt <= t; cnt++) {
    cin >> n;
    for (int i = ; i < n; i++) {
    p[i].x = read();
    p[i].y = read();
    }
    printf("Case %d: ", cnt);
    printf("%.7lf\n", Graham());
    }
    return ;
    }

LightOJ 1203--Guarding Bananas(二维凸包+内角计算)的更多相关文章

  1. LightOJ 1203 Guarding Bananas (凸包最小顶角)

    题目链接:LightOJ 1203 Problem Description Once there was a lazy monkey in a forest. But he loved banana ...

  2. 计算几何 二维凸包问题 Andrew算法

    凸包:把给定点包围在内部的.面积最小的凸多边形. Andrew算法是Graham算法的变种,速度更快稳定性也更好. 首先把全部点排序.依照第一keywordx第二keywordy从小到大排序,删除反复 ...

  3. 使用Graham扫描法求二维凸包的一个程序

    #include <iostream> #include <cstring> #include <cstdlib> #include <cmath> # ...

  4. luogu P2742 【模板】二维凸包 / [USACO5.1]圈奶牛Fencing the Cows

    题解: 二维凸包裸题 按照x坐标为第一关键字,y坐标为第二关键字排序 然后相邻判断叉积用单调队列搞过去 正反都做一次就好了 代码: #include <bits/stdc++.h> usi ...

  5. Luogu P2742 模板-二维凸包

    Luogu P2742 模板-二维凸包 之前写的实在是太蠢了.于是重新写了一个. 用 \(Graham\) 算法求凸包. 注意两个向量 \(a\times b>0\) 的意义是 \(b\) 在 ...

  6. 【洛谷 P2742】【模板】二维凸包

    题目链接 二维凸包板子..有时间会补总结的. #include <cstdio> #include <cmath> #include <algorithm> usi ...

  7. poj 2079 Triangle (二维凸包旋转卡壳)

    Triangle Time Limit: 3000MS   Memory Limit: 30000KB   64bit IO Format: %I64d & %I64u Submit Stat ...

  8. poj 2187 Beauty Contest(二维凸包旋转卡壳)

    D - Beauty Contest Time Limit:3000MS     Memory Limit:65536KB     64bit IO Format:%I64d & %I64u ...

  9. UVA 10652 Board Wrapping(二维凸包)

    传送门 刘汝佳<算法竞赛入门经典>P272例题6包装木板 题意:有n块矩形木板,你的任务是用一个面积尽量小的凸多边形把它们抱起来,并计算出木板占整个包装面积的百分比. 输入:t组数据,每组 ...

随机推荐

  1. 前端使用nginx上传文件时,进度获取不对

    在使用iview时,上传文件获取进度时onUploadProgress返回数据不对. 原因是开启了nginx代理,本地上传时先传到本地nginx然后在传到服务器,导致获取进度不对 解决:在nginx的 ...

  2. sass语法一(变量篇)

    文件后缀名 sass有两种后缀名的文件:一种后缀名为sass,不使用大括号和分号:另一种是我们这里使用的scss文件,这种和我们平时使用的css文件格式差不多,使用大括号和分号. //后缀名为sass ...

  3. div,css&table布局有哪些区别

    DIV+CSS布局与TABLE布局相比,有哪些优点? 1.代码少,页面文件小,下载快 Div+css的布局现在属于国际W3C标准,table不是. 都知道用div的布局代码肯定少,所有的样式都在CSS ...

  4. <Android Framework 之路>BootAnimation(2)

    前言 上一篇主要讲解了BootAnimation是从何而来,如何启动,从开机,到SurfaceFlinger服务起来,然后到执行开机动画,如果要深入的看里面的代码,是需要花一定的时间的,我们旨在了解大 ...

  5. C++类继承--基类new和用派生类new的区别

    实际上无论是用基类还是派生类New, 结果是一样的: #include <stdio.h> class Base { public: int a; Base(){ a=0; } virtu ...

  6. easyui汉化啊!

    <script type="text/javascript" src="__PUBLIC__/jquery-easyui-1.4.4/locale/easyui-l ...

  7. 浅谈PVC塑料配方计算软件的设计

    1, 配方设计与配方计算 题目是配方计算,不是配方设计,设计是需要有深厚的塑料知识才可以做的,即生产什么塑料产品,需要放各种原料是什么,各自比较是多少,遇到什么情况下就要多放什么,少放什么.配方设计不 ...

  8. 获取当前时间CTime

    std::string getcurtime(){ USES_CONVERSION; CTime z_CurTime; CString z_TimeStr; z_CurTime = CTime::Ge ...

  9. 微软发布SQL Server on Linux

    本文参考并翻译自:微软云计算与企业执行副总裁Scott Guthrie的博客. 过去的一年,不管是对于微软的数据业务,还是整个行业,都是令人惊喜的一年.在周四刚于纽约举行的Data Driven活动中 ...

  10. Java中short、int、long、float、double的取值范围

    一.基本数据类型的特点,位数,最大值和最小值.1.基本类型:short 二进制位数:16 包装类:java.lang.Short 最小值:Short.MIN_VALUE=-32768 (-2的15此方 ...